TypeDB Learning Center
Navigating Multi-Way Relationships with TypeDB
Graph databases are well known for their ability to naturally and efficiently represent highly interconnected data. Unlike relational databases, which focus primarily on the individual entities, the primary focus of graph databases is on the connections between them. These connections represent relationships in our conceptual models of data domains.
However, graph databases fall short when describing multi-way relationships, those that link more than two entities. In this article, we examine how graph databases struggle to describe these relationships in an intuitive and maintainable manner, and how TypeDB does so thanks to its high-level conceptual data model.
Relationships in conceptual models
When modeling data, we typically think in terms of entities and relations, as well as the attributes they have. This is due in part to the popularity of Chen’s entity-relationship (ER) model for designing relational databases schemas, but is also considered to be an accurate representation of how we naturally describe the world.
ER models have three key components:
- Entity types: Used to represent classes of independent concepts.
- Relationship types: Used to represent classes of relationships between concepts.
- Attributes types: Used to represent classes of properties belonging to concepts.
ER models are normally illustrated using entity-relationship diagrams (ERDs). In an ERD, entities are represented as rectangles, relationships as diamonds, and attributes as ovals. Lines are used to connect relationships to the entities they relate, and attributes to the concepts they describe. Additional annotations are sometimes used to illustrate specific model features, such as roles on relationships.
How graph models represent relationships
The influence of ER modeling is strongly apparant in the design of modern graph databases, which mostly implement the labeled property graph (LPG) model. Though exact terminology differs among graph databases, the underlying LPG model is almost identical, and consists of four key components:
- Vertices: Used to represent entities.
- Edges: Used to represent relationships. Connect vertices and may be directed.
- Properties: Used to represent attributes. Attached to vertices and edges.
- Labels: Used to represent the types of vertices and edges.
Because of their similar styles of data representation, ER models are very easy to map onto LPG models, which makes graph databases powerful tools for capturing conceptual data models in the most natural form.
Going beyond binary relationships
The LPG model initially seems capable of easily describing relationships in conceptual data models, but this does not apply to all relationships. Edges link two vertices, but not all relationships link two entities. Let’s examine some examples:
- A purchase, which is a three-way relationship between a buyer, a seller, and a product.
- A marriage, which is a five-way relationship between two spouses, two witnesses, and an officiant.
In general, a relationship between an arbitrary number of entities is called a multi-way relationship. They occur naturally in many different data domains, even the most simple ones as we have just seen. However, because edges in a graph database can only link two vertices, we cannot use them to model multi-way relationships! Instead, they have to be represented using vertices.
Using TypeQL’s conceptual syntax
Unlike graph databases, which are based on the LPG model, TypeDB is based on the PERA model (Dorn, Pribadi, 2024) an extension of the ER model. This means it can directly implement multi-way relationships. Let’s examine the TypeQL syntax we use to describe relationships in TypeDB. First, we define a new relation type (along with a few other types). We’ll use the example of a binary group membership.
define
membership sub relation,
relates group,
relates member;
person sub entity,
owns name,
plays membership:member;
group sub entity,
owns name,
plays membership:group;
name sub attribute, value string;
We use the sub
keyword to define a new type, and the relates
keyword to define a role of a relation type. Next, we’ll insert some data.
insert
$alice isa person, has name "Alice";
$bob isa person, has name "Bob";
$group isa group, has name "Used Tech Marketplace";
(group: $group, member: $alice) isa membership;
(group: $group, member: $bob) isa membership;
TypeQL’s relation tuple syntax describes relations by listing their roleplayers as elements. Both the definition and manipulation syntax can be easily extended to describe multi-way relationships, for instance purchases.
define
purchase sub relation,
relates buyer,
relates seller,
relates product,
owns date;
person plays purchase:buyer,
plays purchase:seller;
product sub entity,
owns name,
plays purchase:product;
date sub attribute, value datetime;
match
$alice isa person, has name "Alice";
$bob isa person, has name "Bob";
insert
$airpods isa product, has name "AirPods Pro 2";
(buyer: $alice, seller: $bob, product: $airpods) isa purchase,
has date 2024-05-25;
Roles can also be played multiple times in the same relation!
define
friendship sub relation,
relates friend;
person plays friendship:friend;
match
$alice isa person, has name "Alice";
insert
$carol isa person, has name "Carol";
$dan isa person, has name "Dan";
$erin isa person, has name "Erin";
(friend: $alice, friend: $carol) isa friendship;
(friend: $dan, friend: $erin) isa friendship;
Easily migrate from binary to multi-way
In a graph database, migrating a data model to expand a binary relationship type into a multi-way relationship type is not a straightforward task. Because binary relationships are represented with edges and multi-way relationships with vertices, there are several steps to the process, with the potential for errors along the way:
- Insert a new vertex and pair of edges between linked vertices.
- Copy the properties of the old binary edges onto the new multi-way vertices.
- Delete the old binary edges.
- Insert additional edges onto the new multi-way vertices.
With TypeDB, the process couldn’t be simpler. Let’s start with a binary marriage, which does not include the witnesses and officiant.
define
marriage sub relation,
relates spouse,
owns date;
person plays marriage:spouse;
match
$carol isa person, has name "Carol";
$dan isa person, has name "Dan";
insert
(spouse: $carol, spouse: $dan) isa marriage,
has date 2024-08-02;
To extend it into a multi-way relation, we simply define the new roles and then add the new roleplayers.
define
marriage relates witness,
relates officiant;
person plays marriage:witness,
plays marriage:officiant;
match
$carol isa person, has name "Carol";
$dan isa person, has name "Dan";
$marriage (spouse: $carol, spouse: $dan) isa marriage;
$alice isa person, has name "Alice";
$erin isa person, has name "Erin";
$bob isa person, has name "Bob";
insert
$marriage (witness: $alice, witness: $erin, officiant: $bob);
Summary
We’ve seen how TypeDB can easily model multi-way relationships without having to resort to unintuitive data structures, and how binary relationships can easily be extended to multi-way relationships in-place, without having to modify existing data. This is because of TypeDB’s conceptual data model, which allows it to easily describe high-level data structures. TypeDB’s advanced model goes further still, and even permits relationships to play roles in other relationships! As a result, TypeDB empowers us to easily build conceptual models that faithfully capture data domains the way we think about them, and are more maintainable and extensible with no additional cost.