Defining schema
How to define a schema
To define or undefine anything in a TypeDB database schema we need:
-
Build the TypeQL query string (see below on this page):
-
See how to define types;
-
See how to define rules;
-
See how to undefine types;
-
See how to undefine rules;
-
See how to modify types
-
-
Connect to a TypeDB database with a SCHEMA session.
-
Run a proper query type (Define/ Undefine) with a query string we built in a WRITE transaction.
-
Commit the transaction to persist the changes.
Define types
Any number of define statements can be combined in a single Define query, requiring only one define
clause with only
one define
keyword at the very beginning.
To define a type use the following syntax:
define
<label> sub <parent type label>
[(, abstract)]
[(, owns <attribute type label> [@annotation])...]
[(, plays <relation type label>:<role>)...];
The define
keyword is used only once per query for any number of statements.
The abstract
keyword makes the type abstract.
The owns
keyword defines an attribute ownership.
The plays
keyword defines a role that this type can play.
See examples
define object sub entity;
In the above example we define the object
type as a subtype of the entity
type, which is a built-in root type.
Here is more complex example:
define
object sub entity;
resource sub object;
file sub resource,
owns path,
owns size-kb,
plays object-ownership:object;
If we try to run this example in an empty database it will throw an error, because the path
and size-kb
attribute
types we mentioned as owned by the file
entity type actually need to exist in the schema.
They can be defined in the schema prior to our query (e.g., if we run this query on the database from the Quickstart page), or we can define them in the same query. To do that, use the following query instead:
define
object sub entity;
resource sub object;
file sub resource,
owns path,
owns size-kb,
plays object-ownership:object;
path sub attribute, value string;
size-kb sub attribute, value long;
object-ownership sub relation,
relates object;
All types, mentioned in a type definition (owned attributes or relation that the type can play a role in) must exist in the schema or be defined in the same query. |
Define entity type
See the Define types section.
No specific syntax for entities.
For more information about entity types see the Entity types section in Type system page.
Define relation type
To define a relation type use the following syntax:
define
<label> sub (<relation type label>)
[(, abstract)]
[(, owns <attribute type label> [@annotation])...]
(, relates <role label>) [(, relates <role label>)...]
[(, plays <relation type label>:<role>)...];
The relates
keyword defines a role of the relation type. There must be at least one role for any relation type.
See example
define
ownership sub relation,
relates owned,
relates owner;
group-ownership sub ownership,
owns ownership-type,
relates group as owned;
In the above example we define:
-
the
ownership
type as a subtype of therelation
root type, with:-
owned
role, -
owner
role;
-
-
and the
group-ownership
type as a subtype of theownership
type, with:-
ownership-type
role, -
group
role, overriding inheritedowned
role, -
inherited
owner
role.
-
For more information about relation types see the Relation types section in Type system page.
Define attribute type
To define an attribute type use the following syntax:
define
<label> sub (<abstract attribute type label>)
[(, abstract)]
, value <value type> [, regex "<regex-expression>"]
[(, owns <attribute type label> [@annotation])...]
[(, plays <relation type label>:<role>)...];
The value
keyword is mandatory and used to define a value type for the attribute.
For more information about attribute types see the Attribute types section in Type system page.
Define rules
To define a rule use the following syntax:
define
rule <rule-label>:
when {
## the conditions
} then {
## the conclusion
};
Rule label must be unique. Defining a rule with existing label will rewrite the old rule with the new one.
The condition definition goes inside the when
clause.
The conclusion definition goes inside the then
clause.
For more information about rules, see the Define rules page.
Undefine
Undefine query is used to remove a type or a rule definition form a schema.
Any number of undefine statements can be combined in a single Undefine query, requiring only one undefine
clause
with only one undefine
keyword at the very beginning.
Undefine types
To undefine a type use the following syntax:
undefine
<label> sub <parent type label>
[(, owns <attribute type label> [@annotation])...]
[(, plays <relation type label>:<role>)...];
The undefine keyword
is used only once per query for any number of statements.
The sub
keyword is used only to remove the type mentioned left from the keyword from a schema.
The parent type label must be a direct or indirect supertype.
The owns
keyword undefines an attribute ownership.
The plays
keyword undefines a role that this type can play.
See examples
Let’s define a few new types to undefine them later.
define
tag sub attribute, value string;
connection sub relation,
relates item;
item sub entity,
owns tag,
plays connection:item;
In the above example we define the tag
attribute type, connection
relation type with the item
role,
and item
entity type, that can owns tag
attribute type and plays connection:item
role.
To undefine an attribute ownership use the following query:
undefine
item owns tag;
To undefine the ability to play the role connection:item
use the following query:
undefine
item plays connection:item;
To undefine the item
entity type (remove it from the schema) use the following query:
undefine
item sub entity;
To be able to remove a type we need to delete all instances of data and all subtypes of this type first. The usage of |
Modification
Modify types
The define statements are idempotent. By sending the same define query twice or more times the very same resulting schema must be achieved as if we send it only once. So types and/or rules will not be duplicated.
We can add ownership of an attribute, annotation to an ownership, or a role to play by just defining the add-on.
See example
Let’s define a new ownership for the item
entity.
define
item owns size;
In the query above we define an ownership of size
attribute by the item
type.
For the query to succeed we need both the item
and the size
types to exist in the schema already.
Rename types
To rename a type (to change its label), use the TypeDB Studio or TypeDB Driver API: Rust, Python, Java, Node.js.
Modify rules
To modify a rule define a new rule with the same label. It will overwrite the existing rule upon commit.
Learn more
In case there is no database schema ready yet, we can use the IAM schema to try all the queries.