Officially out now: The TypeDB 3.0 Roadmap >>

Lesson 5: Defining schemas

Defining individual types

  • Define queries are used to define new types, interfaces, and rules. They comprise a define clause only. Define queries are run using a schema session and write transaction.

    define
    # define clause
  • A sub statement is used to define a new subtype of an existing type. All types are subtypes of one of the three root types: entity, relation, or attribute.

    entity-type sub entity;
  • Define queries cannot contain variables, only keywords and type labels.

  • A relates statement is used to define a new role for a relation type. All relation types must have at least one role defined.

    relation-type relates role;
  • A plays statement is used to define a new roleplayer for a role.

    entity-type plays role;
  • A value statement is used to define the value type of an attribute type. All attribute types must have a value type defined: one of boolean, long, double, string, or datetime.

    attribute-type value boolean;
  • An owns statment is used to define a new owner of an attribute type.

    entity-type owns attribute-type;

Defining type hierarchies

  • A type hierarchy can be defined by using an existing type instead of a root type in a sub statement.

    entity-type sub supertype;
  • A subtype of an entity or relation type will inherit all of its owned attributes and played roles.

  • An abstract statement is used to define a type as abstract.

    entity-type abstract;
  • By default, a subtype of a relation type will inherit all of its roles. Inherited roles can be overridden using the as keyword. An overriding role is the subtype of the role it overrides.

    relation-type relates role as overridden-role;
  • To define subtypes of an attribute type, that attribute type must be abstract.

Defining constraints

  • A regex statment is used to constrain the values of a string attribute type with a Java regex pattern

    attribute-type regex "^java regex pattern$";
  • Annotations can be used to constrain attribute ownerships by applying them to owns statements.

  • A @key annotation is used to define a key constraint on an attribute ownership, requiring that instances of the owner type own exactly one instance of the attribute type, and that it must be uniquely owned by the owner type.

    entity-type owns attribute-type @key;
  • A @unique annotation is used to define a unique constraint on an attribute ownership, requiring that instances of the attribute type are uniquely owned by the owner type.

    entity-type owns attribute-type @unique;

Defining rules

  • A rule definition has three components: a rule label, a condition, and a conclusion. A rule definition begins with the rule keyword. The when and then keywords precede the condition and conclusion blocks respectively.

    rule rule-label:
        when {
            # condition
        } then {
            # conclusion
        };
  • The condition block can contain any number of simple or composite statements.

  • The condition block must contain only one simple statement.

  • A rule must generate either a single new relation or a single new attribute.

  • Every variable in the conclusion must also appear in the condition.

Schema validation

  • Checks must be passed whenever changes to the schema are made to ensure internal consistency.

  • Making changes that fail a validation check will cause an exception to be thrown.

  • Rules undergo the same validation as Insert queries.

Further learning

Learn how to build applications on TypeDB, covering database management, transaction control, and result stream processing.

Learn how to build query patterns utilising advanced elements of TypeQL syntax, and how queries are resolved by TypeDB.

Learn more about defining schemas for TypeDB, covering Define queries, Undefine queries, and schema editing.