Defining types
This page explains how to define types and type traits in TypeDB schemas.
Schema definition queries
All schema (un)definitions in TypeDB are run in schema
transactions. There are three kinds of schema definition queries:
-
define <statements>
. Adefine
query defines types and their traits, subtyping, as well as more specific annotations on those statements. -
undefine <statements>
. Anundefine
query can be used to remove definitions of type, their traits, subtyping, and statement annotations. -
redefine <statement>
. Aredefine
query can be used to change a single statement at a time, overwriting any analogous previously defined statement.
Entity types
Entity types are first defined using the entity
keyword.
define entity user;
Subtypes of entity types are always entity types themselves, and can be introduced using the sub
keyword.
define entity admin sub user;
Traits of entity types are defined as before using the plays
and owns
keywords.
Relation types
Relation types are first defined using the relation
keyword.
define
relation friendship,
relates friend @card(2);
Here, @card(2)
is an example of annotation, specifying that there will be exactly two friends in each friendship relation. Without this annotation the role cardinality would default to @card(0..1)
(allowing between 0 and 1 friend). See annotations for more.
Subtypes of relation types are always relation types themselves, and can be introduced using the sub
keyword.
-
Relation subtypes can specialize the roles of their supertype using the
as
keyword. -
Otherwise, if a role is not specialized, relations subtypes automatically inherit that role.
For example
define
relation close-friendship sub friendship; # inherits friend role
relation best-friendship sub friendship, # specializes friend role
relates best-friend as friend @card(1),
relates other-friend as friend @card(1);
This defines “close friendship” and “best-friendship” relations as a subtype of our friendship relations above.
Note that unlike friendship relations, the subtype of best-friendships contains asymmetric relations (indeed, unfortunately, if A is the best friend of B this need not imply that B is the best friend of A). In general, a single role can be specialized into any number of roles, as long as role cardinalities are compatible.
In the above example, the cardinality annotations |
Traits of relation types are defined as before using the plays
and owns
keywords.
Attribute types
Attribute types are first defined using the attribute
keyword, and they must be supplied with a value type using the value
keyword (unless, they are annotated as being @abstract
, see annotations)
define
attribute id,
value string;
Subtypes of attributes types are always attributes types themselves, and inherit the value type of its supertype (if set; otherwise, a new value type can be set). For example:
define
attribute comment-id sub id;
Recall that attributes do not play roles or own other attributes. |
Undefining definitions
Any of the above statements can be undefined. For example
undefine entity admin;
will completely remove the admin from your schema, and with it all traits of the admin type.
Removing a type from your schema will, in general, only succeed if there are no data instance in the type and no other definitions depend on the type (i.e., the type appears neither in another type’s trait nor as another type’s supertype). |
If we instead write
undefine sub user from admin;
then this removes admin
having user
as its supertype, but it does not remove the type admin
itself.
Similarly, writing
undefine plays friendship:friend from user;
removes the friend trait from the user type, but leaves the type itself intact. And
undefine owns username from user;
removes the trait of owning usernames.
Redefining definitions
TypeDB also allows concise redefinitions of single statements. For example, after we define
define
entity user;
entity admin sub user;
entity superuser sub user;
we may redefine:
redefine admin sub superuser;
This will turn the initial tree-like
type hierarchy into a linear type hierarchy, where admin < superuser < user
.
Re-define semantics are the most complex of all three definition queries. However, the simple key property of redefine is: after a successful redefinition, the re-defined statement holds fully, replacing any conflicting prior statement.
While both |