Schema
Schemas control your database’s structure and behavior.
Fauna Schema Language
In Fauna, you define schemas using Fauna Schema Language (FSL). You use FSL to create and update schemas for:
-
Access providers for authentication
-
Collections, including document types
Manage schemas as FSL files
You can manage FSL schemas as .fsl
files and use the Fauna CLI to push
changes to Fauna. This lets you version control, review, and automate schema
changes.
See Get started with schema management |
---|
Collection schema
Reference: Collection schema |
---|
A collection schema defines the structure and behavior of a collection and its documents. It can include:
-
A document type definition that controls what fields are accepted in a collection’s documents. The document type definition consists of:
-
Field definitionsthat define document fields
-
A wildcard constraint that allows or disallows arbitrary ad hoc fields in documents
-
-
A migrations block for handling changes to the document type
-
Index definitions for efficient querying
-
Unique constraints to ensure fields contain unique values
-
Check constraints for data validation
You create and manage collection schemas in FSL:
collection Product {
// Field definitions.
// Define the structure of the collection's documents.
name: String?
description: String?
price: Double = 0.00
quantity: Int = 0
creationTime: Time = Time.now()
creationTimeEpoch: Int?
typeConflicts: { *: Any }?
// Wildcard constraint.
// Allows or disallows arbitrary ad hoc fields.
*: Any
// Migrations block.
// Used for schema migrations.
// Instructs Fauna how to handle updates to a collection's
// field definitions and wildcard constraint.
// Contains imperative migration statements.
migrations {
add .typeConflicts
add .quantity
backfill .quantity = 0
drop .internalDesc
move_conflicts .typeConflicts
move .desc -> .description
split .creationTime -> .creationTime, .creationTimeEpoch
}
// Index definition.
// You use indexes to filter and sort documents
// in a performant way.
index byName {
terms [.name]
values [desc(.quantity), desc(mva(.categories))]
}
// Unique constraint.
// Ensures a field value or combination of field values
// is unique for each document in the collection.
// Supports multivalue attribute (`mva`) fields, such as arrays.
unique [.name, .description, mva(.categories)]
// Check constraint.
// Ensures a field value meets provided criteria
// before writes. Written as FQL predicate functions.
check posQuantity ((doc) => doc.quantity >= 0)
// Computed field.
// A document field that derives its value from a
// user-defined, read-only FQL function that runs on every read.
compute InventoryValue: Number = (.quantity * .price)
// Controls whether you can write to the `ttl` field for collection
// documents. If the collection schema doesn't contain field
// definitions, `document_ttls` defaults to `true`. Otherwise,
// `document_ttls` defaults to `false`.
document_ttls true
// Sets the default `ttl` for documents in days from their creation
// timestamp. Ignored if `document_ttls` is false. You can override
// the default ttl` during document creation.
ttl_days 5
// Controls document history retention.
history_days 3
}
Document type definitions
A collection’s schema can include a document type definition. The definition controls what fields are accepted in a collection’s documents. You define a document’s type using:
Field definitions and schema migrations are in beta. A schema migration is required to change a collection’s field definitions or wildcard constraint. By performing a schema migration, you automatically opt-in to the beta. During beta, schema migrations triggers a rebuild of all of a collection’s indexes. This can make large indexes unusable for extended periods. To register for the beta and sign up for production support, go to https://go.fauna.com/schemabetaproductionsupport. |
Field definitions
Reference: Field definitions |
---|
Field definitions define fields for a collection’s documents. A field definition consists of:
-
A field name
-
Accepted data types for the field’s values
-
An optional default value
You can use field definitions to:
-
Ensure each document in a collection contains a specific field
-
Limit a field’s values to specific types
-
Set a default value for documents missing a field
-
Enumerate accepted values
collection Product {
// `name` is optional (nullable).
// Accepts `String` or `null` values.
name: String? // Equivalent to `name: String | Null`
// `price` is optional (nullable).
// Accepts `Double` or `null` values.
price: Double?
// `quantity` is non-nullable.
// Accepts only `Int` values.
// If the field is missing on create, defaults to `0`.
quantity: Int = 0
// `creationTime` is non-nullable.
// Accepts only `Time` or `Number` values.
// If `null` or missing, defaults to the current time.
creationTime: Time | Number = Time.now()
// `category` is non-nullable.
// Accepts only the enumerated "grocery",
// "pharmacy", or "home goods" values.
// If `null` or missing, defaults to "grocery".
category: "grocery" | "pharmacy" | "home goods" = "grocery"
}
Wildcard constraint
Reference: Wildcard constraints |
---|
An ad hoc field is an arbitrary document field that doesn’t have a field definition.
You can use a collection schema’s wildcard constraint to allow or disallow ad hoc fields in the collection’s documents.
collection Product {
name: String? // Equivalent to `name: String | Null`
...
// Wildcard constraint.
// This example accepts ad hoc fields of any type.
*: Any
}
Computed fields
Reference: collection.compute |
---|
Computed fields derive their field value from a provided function. They let you create new fields based on existing data or calculations.
You can use a computed field to:
-
Combine or transform other field values
-
Assign a value based on an
if ... else
expression -
Assign a value based on one or more ranges
Computed fields aren’t part of the original document or persistently stored. Instead, the field’s value is computed on each read.
Document type enforcement
Fauna rejects attempts to write documents that don’t conform to a collection’s field definitions and wildcard constraint.
You can use the collection’s field definitions and wildcard constraint to adjust how strictly you enforce a predefined structure on collection documents:
Strategy | Description | Field definitions | Wildcard constraint |
---|---|---|---|
Schemaless |
Accepts ad hoc fields of any type. No fields are predefined. |
No field definitions |
No wildcard constraint |
Permissive |
Accepts ad hoc fields and predefined fields. Fields must conform to the structure of their definitions. |
One or more field definitions |
A wildcard constraint |
Strict |
Only accepts predefined fields |
One or more field definitions |
No wildcard constraint |
Schemaless by default
If a collection has no field definitions, it’s schemaless by default. It implicitly accepts ad hoc fields of any type.
Progressive enforcement
Using permissive document types is often helpful earlier in an application’s development. Allowing ad hoc fields lets you add fields as needed.
As your data evolves, you can use zero-downtime migrations to add field definitions for ad hoc fields and normalize field values. This lets you move from a permissive document type to strict one (or the reverse).
Tutorial: Progressively enforce a document type |
---|
Zero-downtime migrations
A schema migration is an update to a collection schema’s field definitions or wildcard constraint. Schema migrations require no downtime or locks on your database. Changes are immediately visible in subsequent queries.
Migrations block
Reference: Migrations block |
---|
To handle migrations, you include a migrations block in the collection schema. The block contains one or more imperative migration statements.
The statements instruct Fauna on how to migrate from the collection’s current field definitions and wildcard constraint to the new ones.
collection Product {
...
*: Any
migrations {
// Applied 2099-05-06
add .typeConflicts
add .quantity
move_conflicts .typeConflicts
backfill .quantity = 0
drop .internalDesc
move .desc -> .description
split .creationTime -> .creationTime, .creationTimeEpoch
// Applied 2099-05-20
// Make `price` a required field.
split .price -> .price, .tempPrice
drop .tempPrice
backfill .price = 10.00
}
}
Run a schema migration
A typical schema migration involves three steps:
-
Update the field definitions and wildcard constraint in the collection schema.
-
Add one or more related migration statements to the collection schema’s migrations block. Include comments to group and annotate statements related to the same migration.
-
Submit the updated collection schema to Fauna using the Fauna CLI or the Fauna Dashboard.
Fauna runs each new migration statement sequentially from top to bottom. Fauna ignores unchanged migration statements from previous migrations.
Changes from the migration are immediately visible in any subsequent queries.
Migration errors
When you submit a collection schema, Fauna checks the schema’s field definitions and migration statements for potential conflicts.
If a change could conflict with the collection’s data, Fauna rejects the schema with an error message. The check doesn’t require a read or scan of the collection’s documents.
Index definitions
An index stores, or covers, specific document field values for quick retrieval. Using indexes can significantly improve query performance and reduce costs, especially for large datasets.
See Indexes |
---|
Unique constraints
Reference: collection.unique |
---|
Unique constraints ensures a field value or combination of field values is unique for each document in a collection. Fauna rejects document writes that don’t meet the constraint.
Check constraints
Reference: collection.check |
---|
Check constraints ensure field values meet a pre-defined rule. For example, you can check that field value is in an allowed range.
You define a check constraint as a read-only FQL
predicate. Fauna only
allows document writes if the predicate evaluates to true`
.
Document retention
A document can include an optional ttl
(time-to-live) field that contains the
document’s expiration timestamp. After the ttl
timestamp passes, Fauna
permanently deletes the document.
You can use a collection schema’s ttl_days
field to set a default ttl
for
collection documents. See
Set a default ttl.
You can use a collection schema’s document_ttls
field to control
whether you can write to the ttl
field for collection documents. See
Enable or
disable ttl writes.
See Document removal |
---|
Document history
Fauna stores snapshots of each document’s history. Fauna creates these snapshots each time the document receives a write.
You can use a collection schema’s history_days
field to set how many days of
document history Fauna retains for a collection’s documents.
See Document history |
---|
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!