Databases and multi-tenancy
In Fauna, a database stores data as documents in one or more collections.
Database model
Fauna’s database model makes it easy to create databases for isolated environments, such as staging and production, and multi-tenant applications:
-
Each Fauna database can have many child databases. You can use child databases as tenants for your application. See Multi-tenancy.
-
All databases, including child databases, are instantly allocated without provisioning or warmup.
-
Each database is logically isolated from its peers with separate access controls. See Isolation and access control.
-
All Fauna resources, except top-level keys, exist as documents within a specific database. This includes collections, user-defined functions, and child databases.
-
Queries run in the context of a single database and can’t access data outside the database. See Scope and routing.
Multi-tenancy
Fauna databases support a hierarchical database structure with top-level and child databases.
Top-level and child databases
Top-level databases exist in an account’s top-level context. All Fauna resources, except top-level keys, exist as documents within a specific database. This includes child databases.
A database can have many child databases, which can also have child databases.
Isolation and access control
You can use Fauna databases to build applications with strong isolation guarantees:
-
Each database is logically isolated from its peers with separate access controls.
-
You can use scoped keys from a parent database to manage and access data in child databases.
-
Child databases can’t access or discover parent or peer databases.
Scope and routing
Each Fauna query is an independently authenticated request to the Query HTTP API endpoint. Each query is a transaction.
Queries run in the context of a single database and can’t access data outside the database.
Queries are routed to a database based on the Query API request’s authentication secret. You can’t use a secret to access a peer or parent database.
Query child databases using scoped keys
A scoped key lets you use a parent database’s admin key to send query requests to its child databases.
For example, if you have an admin key for a parent database and want to
connect to a child database named childDB
, you can create a scoped key using
the following format:
// Scoped key that impersonates an `admin` key for
// the `childDB` child database.
fn...:childDB:admin
See Scoped keys |
---|
Database
collection
Fauna stores metadata and settings for a database’s child databases as documents
in the Database
system collection. These documents have the DatabaseDef type.
You can use
Database
collection
methods to create and manage databases in FQL.
The Database
collection only contains direct child databases of the database
scoped to your authentication secret. You can’t use the Database
collection to
access parent, peer, or other descendant databases.
If you use an authentication secret scoped to an account’s top-level context,
the Database
collection contains documents for the account’s top-level
databases. You can create a top-level secret using the
Fauna CLI's
fauna cloud-login
command.
See Database FQL docs |
---|
Global database ID
Each Database
document contains an auto-generated, globally unique ID for the
database:
{
name: "ECommerce",
coll: Database,
ts: Time("2099-06-24T21:54:38.890Z"),
// Globally unique id for the `ECommerce` database.
global_id: "ysjpykbahyyr1",
priority: 10,
typechecked: true
}
Applications and external systems can also use this ID to identify a Fauna database.
For example, Fauna access providers
use a database’s globally unique ID in the audience URL, which must be included
in the aud
(audience) claim of JWTs issued by the provider. Fauna uses this
URL to authenticate query requests and route them to a specific database.
Create and manage databases
You can create and manage databases using:
Authentication for top-level databases
To create or manage a top-level database using the Fauna CLI,
you must use an authentication secret scoped to the account’s top-level context.
You can create a top-level secret using the Fauna
CLI's fauna cloud-login
command.
Authentication for child databases
To create or manage a child database using the Fauna CLI or an FQL query, you must use an authentication secret scoped to the parent database.
Create a database
You can create a database using the Fauna
Dashboard or the Fauna CLI's
fauna create-database
command:
fauna create-database ECommerce
You can use
Database.create()
to
programmatically create child databases database using an FQL query:
Database.create({
name: "ECommerce",
typechecked: true
})
Using FQL to create or manage top-level databases is not supported.
Manage a database’s schema
You can use schema to control a database’s
structure and behavior. You manage schema using the
Fauna Dashboard or as .fsl
files using the
Fauna CLI.
For example, the following
fauna schema push
command
stages a schema change using the
CLI:
fauna schema push
You can also create a CI/CD pipeline to copy and deploy schema across databases.
See Schema |
---|
Manage schema for child databases
You can manage schema for child databases using scoped keys with the Fauna CLI or using FQL schema methods.
Use scoped keys
Most schema-related Fauna CLI commands support a --secret
option. Use this
option to provide a scoped key,
letting you interact with a child database’s schema using a parent database’s
admin key.
For example, with a parent database’s admin key secret of fn123
, you can
access a child database by appending the child database name and role:
# Uses a scoped key from a parent database
# to stage schema in the `childDb` child database.
# The scope key has `admin` privileges in the
# `childDb` database.
fauna schema push --secret:fn123:childDb:admin
Use FQL schema methods
Fauna stores each schema for a database as an FQL document in a related system collection.
You can use methods for these system collections to programmatically manage the schema of child databases using FQL queries.
FSL schema | FQL system collection |
---|---|
Rename a database
You can rename a database using the Fauna
Dashboard. You can also use
database.update()
to rename a
child database in an FQL query:
// Renames the `ECommerce` database to `ECommerceStore`.
Database.byName("ECommerce")!.update({
name: "ECommerceStore"
})
Renaming a database preserves any inbound references to the database. Data in a renamed database remains accessible using existing keys.
Delete a database
You can delete a database using the Fauna Dashboard or the
Fauna CLI's
fauna delete-database
command:
fauna delete-database ECommerce
You can also use database.delete()
to delete a child database in an FQL query:
// Deletes the `ECommerce` database.
Database.byName("ECommerce")!.delete()
Considerations
When you delete a database, its data becomes inaccessible and is asynchronously deleted. As part of the deletion process, Fauna recursively deletes:
-
Any keys scoped to the database.
-
The database’s child databases, including any nested databases.
Deleting a database with a large number of keys can exceed
Transactional
Write Ops throughput limits. This can cause
throttling errors with a
limit_exceeded
error
code and a 429 HTTP status code.
Deleting a database with a large number of child databases can cause timeout
errors with a time_out
error code and a 440 HTTP
status code.
To avoid throttling or timeouts, incrementally delete all keys and child databases before deleting the database. See delete all keys and delete all child databases.
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!