Lesson 5: Defining schemas

Defining individual types

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

    define
    # define clause
  • A entity, relation, or attribute kind statement is used to define a new type. You can use sub to attach new types to other types as a subtype.

    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 role player 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.

    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 using 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 annotation 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;

Defining data constraints

  • A @card annotation controls the connectivity of your dataset

  • A @regex annotation can be used to constrain string attribute type by regex

  • A @values annotation can be used to constrain any value type to set a possible values

  • A @range annotation can be used to constraint any numerical value type

    attribute attribute-type @regex("^regex pattern$");
  • 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 functions

  • A function definition has three components: a signature, a body, and a return.

    fun function-name($arg: arg-type) -> { return-type }:
      <body>
      return <return operation>;
  • The body can be any read-only query pipeline

  • The return operation must match the declared signature

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.

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.