Data modeling best practices
This guide covers best practices for modeling data in Fauna.
Use indexes for commonly accessed data
Indexes are the most important and effective tool to increase performance and reduce the cost of your queries.
Avoid uncovered queries whenever possible. To reduce document reads, include any frequently queried fields in indexes.
See Indexes |
---|
Use computed fields to reduce storage
If you’re storing a large amount of data, you can use computed fields to reduce storage where applicable.
Computed fields aren’t part of the original document or persistently stored. Instead, the field’s value is computed on each read.
To avoid unneeded computes on read, use projection to only request computed fields when needed in queries.
See Computed field definitions |
---|
Use schema to progressively enforce document types
Use a collection schema’s document type to check the presence and type of document field values on write. You use document types to enforce enumerated field values and allow arbitrary ad hoc fields.
If your application’s data model changes, 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).
See Schema |
---|
Validate data with constraints
Use constraints to validate field values using predefined rules.
For example, you can use a unique constraint to ensure each end user has a unique email address.
Similarly, you can use a check constraint to apply other business logic. For example, you can ensure:
-
age
field values are greater than zero -
Projects are scheduled in the future
-
Purchases don’t reduce a user’s
balance
to a negative number
See Unique constraints, Check constraints |
---|
Use ttl
for document retention
Use the optional ttl
(time-to-live) document metadata field to automatically
clean up completed or obsolete documents. ttl
sets an expiration timestamp for
the document.
Set a default retention period for a collection’s documents using the
collection schema's ttl_days
field.
See Document time-to-live (TTL) |
---|
For multi-tenant apps, use a child database per tenant
You can use FQL queries or the Fauna CLI to programmatically create a child database per tenant. Databases are instantly allocated.
Using child databases lets you build multi-tenant applications with strong isolation guarantees. Each database is logically isolated from its peers, with separate access controls. You can manage all tenants from a single parent database.
Avoid creating a collection for each tenant. Collections don’t offer strong isolation or separate access controls. A database can only contain 1,024 collections. |
Use CI/CD to manage schemas across databases
An FSL schema is scoped to a single database and doesn’t apply to its peer or child databases.
If you have a multi-tenant application, you can copy and deploy schema across databases using FSL and a CI/CD pipeline. See Manage schemas with a CI/CD pipeline.
Avoid concurrent schema changes
Concurrent schema writes in the same database can cause contended transactions, even if the changes affect different schemas. This includes schema changes made using:
-
The Fauna Dashboard.
-
The Fauna CLI's
schema push
command. -
FQL methods, such as
Collection.create()
orrole.update()
, that write to a schema’s underlying document.
A schema change triggers a transaction that validates all schemas for the database. To avoid errors, perform schema changes sequentially instead.
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!