# Entities, Relations, Attributes

TypeDB implements the Polymorphic Entity-Relation-Attribute (PERA) data model. A TypeDB schema defines a hierarchy of these types and how they interact with each other through interface types.

## [](#_entity)Entity

Entities are standalone types, which exist independent of other types.

E.g., a `person` exists, regardless of whether they are involved in friendships or have a name.

```typeql
#!test[schema]
define
entity person;
entity company;
```

## [](#_relation)Relation

Relations are types which define one-or-more associated interface types called "role"s. The relation depends on other types in the schema to implement these interfaces by "playing" these roles.

E.g., an `employment` relation exists to relate an `employer` to an `employee`. An `employment` instance cannot exist without the other instances which play these roles, hence the idea that `employment` "depends" on the participating player types.

```typeql
#!test[schema]
define
relation employment,
  relates employer,
  relates employee;
```

Role type names exist scoped within their relation types, allowing you to re-use role labels in different relation types:

```typeql
#!test[schema]
define
relation employment,
  relates employer,
  relates employee;

relation insurance-obligation,
  relates employer,
  relates employee,
  relates insurance;
```

You can refer to a role distinctly by scoping the role name with the relation name: `employment:employer`.

## [](#_attribute)Attribute

Attributes are types which hold a value. An attribute type must specify the primitive `value` type of the values it will hold.

An instance of an attribute type is identified by its value.

E.g., any instance which has an age of 10 will refer to the same instance of the `age` attribute type.

An attribute declares an implicit ownership interface. A type can be defined to implement this interface using the `owns` keyword.

```typeql
#!test[schema]
define
attribute age, value integer;
```

## [](#_owning_attributes_playing_roles)Owning attributes & playing roles

Entity & relation types may be defined to "own" attribute types. Unlike attributes, which are identified by their values, there is no direct way to reference an entity. Hence, entities (or relations) are referenced through their attributes.

E.g., a `person` may own an attribute `birth-date`, or an `employment` may own a `start-date`.

```typeql
#!test[schema]
define
person owns age;
```

Entity & relation types may be defined to "play" a role defined by a relation.

E.g., the entity type `company` may play the `employer` role of an `employment` relation.

```typeql
#!test[schema, rollback]
define
company plays employment:employer;
```

## [](#_inheritance)Inheritance

TypeDB follows a single-inheritance **subtyping** system which allows types to specialize an existing type. The subtype inherits all declared interfaces & implementations from the supertype.

Inheritance in the social network

```typeql
#!test[schema, commit]
#{{
define
attribute name, value string;
attribute username, value string;
attribute profile-picture, value string;
relation posting, relates page, relates post;
relation viewing, relates viewer, relates viewed;
relation content-engagement, relates author;
relation group-membership, relates group, relates member;
#}}
# Some fields are left out for brevity
# A page on a social network...
#!test[schema]
define
entity page @abstract,
    owns name,              # has some basic information,
    owns profile-picture,   #
    plays posting:page,     # can create posts
    plays viewing:viewed;   # for others to view

# A profile has a page, but also the agency of a user:
entity profile, sub page,
    owns username,                   # has a username,
    plays group-membership:member,   # can participate in groups,
    plays viewing:viewer,            # view posts,
    plays content-engagement:author; # and create posts
```

In this context, a page is a passive collection of posts for other users to view. A profile retains all the aspects of being a page - It has a name and a profile-picture, It can contain posts, and be viewed by others. It also has the agency of a being user - It has a username for logging in, It can create new posts, view them, and participate in groups.

### [](#_specializing_role_types)Specializing role types

A subtype also inherits any interfaces (such as roles) defined by its supertype. It may optionally "specialize" an inherited interface.

In the following schema snippet, `content-engagement` inherits the `content` role from `interaction` as-is, and "specializes" the inherited `subject` role into the `author` role.

```typeql
#!test[schema, rollback]
define
relation interaction @abstract,
    relates subject,
    relates content;
relation content-engagement @abstract,
    sub interaction,
    relates author as subject;
```

Specialization also disallows implementations of the parent interface in the child type. Here, no instances can play the role `interaction:content` in `content-engagement` relations.

An attribute type also inherits and implicitly specialises the interface of its supertype.

## [](#_polymorphism)Polymorphism

Polymorphism in TypeDB is realized in two ways:

### [](#_interfaces)Interfaces

Multiple types may "implement" the same interface - i.e. play the same role, or own the same attribute. This is a form of polymorphism we call **"interface polymorphism"**.

In the following schema snippet, the `employer` role in the `employment` relation can be played by a `company` or an `charity`.

```typeql
#!test[schema, rollback]
define
  relation employment,
    relates employer,
    relates employee;

  entity organization;
  entity company sub organization,
    plays employment:employer;
  entity charity sub organization,
    plays employment:employer;
```

Here, the role `employer` is the interface declared by the `employment` type. The `company` and `charity` types implement the interface. The `relates` keyword is used to define the new role type interface. The `plays` keyword is used to implement a role type interface. Similarly, the `owns` keyword can be used to implement the implicit ownership interface of an attribute.

### [](#_subtyping)Subtyping

Since a subtype "inherits" all owns or plays implementations from its supertype, an instance of the subtype may be used at any interface (or function argument/return) that expects an instance of its super-type.

In the following schema snippet, entities of type `company` or `charity` can play the `employer` in an `employment`, although it is their supertype `organization` which is defined to play the role.

```typeql
#!test[schema, rollback]

define
  relation employment,
    relates employer,
    relates employee;

  entity organization,
    plays employment:employer;
  entity company sub organization;
  entity charity sub organization;
```

## [](#_references)References

*   [Type system](../../../typeql-reference/data-model/index.md#_type_system)
    

[TypeQL](../index.md) [Constraining Data](../constraining-data/index.md)

[Edit on GitHub](https://github.com/typedb/typedb-docs/edit/3.x-development/core-concepts/modules/ROOT/pages/typeql/entities-relations-attributes.adoc) Edit this page on GitHub.