This page is indended as a rapid-fire overview of EdgeDB’s schema definition language (SDL) so you can hit the ground running with EdgeDB. Refer to the linked pages for more in-depth documentation!
EdgeDB implements a rigorous type system containing the following primitive types.
Strings |
|
Booleans |
|
Numbers |
|
UUID |
|
JSON |
|
Dates and times |
|
Durations |
|
Binary data |
|
Auto-incrementing counters |
|
Enums |
|
These primitives can be combined into arrays, tuples, and ranges.
Arrays |
|
Tuples (unnamed) |
|
Tuples (named) |
|
Ranges |
|
Collectively, primitive and collection types comprise EdgeDB’s scalar type system.
Object types are analogous to tables in SQL. The can contain properties—which can correspond to any scalar type— and links—which correspond to other object types.
The property
keyword is used to declare a property.
type Movie {
property title -> str;
}
Properties are optional by default. Use the required
keyword to make them
required.
type Movie {
required property title -> str; # required
property release_year -> int64; # optional
}
See Schema > Properties.
Add a pair of curly braces after the property to define additional information, including constraints.
type Movie {
required property title -> str {
constraint exclusive;
constraint min_len_value(8);
constraint regexp(r'^[A-Za-z0-9 ]+$');
}
}
See Schema > Constraints.
Object types can contain computed properties that correspond to EdgeQL expressions. This expression is dynamically computed whenever the property is queried.
type Movie {
required property title -> str;
property uppercase_title := str_upper(.title);
}
See Schema > Computeds.
Object types can have links to other object types.
type Movie {
required property title -> str;
link director -> Person;
}
type Person {
required property name -> str;
}
Use the required
and multi
keywords to specify the cardinality of the
relation.
type Movie {
required property title -> str;
link cinematographer -> Person; # zero or one
required link director -> Person; # exactly one
multi link writers -> Person; # zero or more
required multi link actors -> Person; # one or more
}
type Person {
required property name -> str;
}
To define a one-to-one relation, use an exclusive
constraint.
type Movie {
required property title -> str;
required link stats -> MovieStats {
constraint exclusive;
};
}
type MovieStats {
required property budget -> int64;
required property box_office -> int64;
}
See Schema > Links.
Objects can contain “computed links”: stored expressions that return a set of objects. Computed links are dynamically computed when they are referenced in queries. The example below defines a backlink.
type Movie {
required property title -> str;
multi link actors -> Person;
# returns all movies with same title
multi link same_title := (
with t := .title
select detached Movie filter .title = t
)
}
A common use case for computed links is backlinks.
type Movie {
required property title -> str;
multi link actors -> Person;
}
type Person {
required property name -> str;
multi link acted_in := .<actors[is Movie];
}
The computed link acted_in
returns all Movie
objects with a link
called actors
that points to the current Person
. The easiest way to
understand backlink syntax is to split it into two parts:
.<actors
This uses a special syntax .<
to return all objects in the database with
a link called actors
that points to the current object. This set could
conceivably contain other objects besides Movie
; for instance, we could
define a TVShow
type that also included link actors -> Person
.
[is Movie]
This is a type filter that filters out all objects that aren’t Movie
objects. A backlink still works without this filter, but could contain any
other number of objects besides `` Movie`` objects.
Constraints can also be defined at the object level.
type BlogPost {
property title -> str;
link author -> User;
constraint exclusive on ((.title, .author));
}
Constraints can contain exceptions; these are called partial constraints.
type BlogPost {
property title -> str;
property published -> bool;
constraint exclusive on (.title) except (not .published);
}
Use index on
to define indexes on an object type.
type Movie {
required property title -> str;
required property release_year -> int64;
index on (.title); # simple index
index on ((.title, .release_year)); # composite index
index on (str_trim(str_lower(.title))); # computed index
}
The id
property, all links, and all properties with exclusive
constraints are automatically indexed.
See Schema > Indexes.
Object types can be declared as abstract
. Non-abstract types can extend
abstract types.
abstract type Content {
required property title -> str;
}
type Movie extending Content {
required property release_year -> int64;
}
type TVShow extending Content {
required property num_seasons -> int64;
}
Multiple inheritance is supported.
abstract type HasTitle {
required property title -> str;
}
abstract type HasReleaseYear {
required property release_year -> int64;
}
type Movie extending HasTitle, HasReleaseYear {
link sequel_to -> Movie;
}
Links can correspond to abstract types. These are known as polymorphic links.
abstract type Content {
required property title -> str;
}
type Movie extending Content {
required property release_year -> int64;
}
type TVShow extending Content {
required property num_seasons -> int64;
}
type Franchise {
required property name -> str;
multi link entries -> Content;
}
See Schema > Links > Polymorphism and EdgeQL > Select > Polymorphic queries.