vaticle / typedb

TypeDB: the polymorphic database powered by types
https://typedb.com
Mozilla Public License 2.0
3.72k stars 337 forks source link

TypeDB 3.0: compound keys and role players as keys #7030

Open flyingsilverfin opened 3 months ago

flyingsilverfin commented 3 months ago

Problem to Solve

TypeDB currently does not have a way to automatically enforce compound keys, nor does it have a way of enforcing uniqueness of relations.

Current Workaround

Users end up manually concatenating two keys into a string, and using that as a separate attribute alongside the existing keys.

Proposed Solution

Compound keys

We introduce a new syntax for compound keys, using labels to denote which keys belong together:

define
  person sub entity,
    owns email @key, // same as before. Note: email[] is not allowed with @key, but is allowed with @unique.
    owns phone @subkey(country-phone-key),
    owns resident-country @subkey(country-phone-key);

Writing @key and @subkey(<label>) onto the same ownership is not permitted, since it completely redundant: a simple @key means that any compound key created with it will already be identified by the single key component.

Additionally, a @subkey label must be used in more than 1 ownership to be meaningful, or the schema must be rejected.

Role players as keys

We also want to allow making role players of relations keys for the relation:

define
  service_invitation sub relation,
    relates user @key,
    relates service;

This will ensure that only one service_invitation exists for a particular invited user - the same as a user plays service_invitation:user @card(1,1). However, this is more useful in this scenario:

define
  service_invitation sub relation,
    relates user @subkey(invited),
    relates service @subkey(invited);

This enforces that there is exactly one relation of this type per combination of user and service