Relationships and Cardinality
Define edges between entities with labels, typed properties, cardinality values, directional control, and FK-generated connections.
Relationships in the data model are edges that connect entity nodes. Each edge defines how two entities relate, with support for labelling, cardinality, directionality, and typed properties. The graph editor renders these edges with cardinality-aware arrow decorations so that structural constraints are visible directly on the canvas.
Edge Structure
Every relationship edge in the model has the following fields.
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier (UUID) for the edge |
| source | string | Node ID of the source entity |
| target | string | Node ID of the target entity |
| label | string | Label displayed at the centre of the edge (e.g., "PLACES", "BELONGS_TO") |
| sourceLabel | string | Label displayed near the source node end |
| targetLabel | string | Label displayed near the target node end |
| properties | GraphEdgeProperty[] | Typed properties on the relationship (same structure as node properties) |
| cardinality | GraphEdgeCardinality | Cardinality constraint from the supported value set |
| directed | boolean | Whether the edge is directed (default: true) |
| note | ShapeNote | Optional note attached to the relationship |
Cardinality Values
The model supports a full set of cardinality expressions that cover all standard relationship multiplicities. Cardinality is displayed in graph-db authoring mode when the mode configuration has showCardinality enabled.
| Cardinality | Source Side | Target Side | Example |
|---|---|---|---|
| 1:1 | Exactly one | Exactly one | A person has exactly one passport |
| 1:N | Exactly one | Many | A customer places many orders |
| N:1 | Many | Exactly one | Many employees belong to one department |
| N:M | Many | Many | Students enrol in many courses, courses have many students |
| 1:0..1 | Exactly one | Zero or one | A user has an optional profile |
| 0..1:1 | Zero or one | Exactly one | An optional billing address belongs to one account |
| 1:0..N | Exactly one | Zero or many | A category contains zero or many products |
| 0..N:1 | Zero or many | Exactly one | Zero or many comments belong to one post |
| 1:1..N | Exactly one | One or many | An order contains at least one line item |
| 1..N:1 | One or many | Exactly one | One or many payments settle one invoice |
Cardinality-aware Arrow Rendering
The graph editor renders different visual decorations on edge endpoints based on the cardinality value. This provides immediate visual feedback about the nature of each relationship.
Edge Properties
Relationships support typed properties with the same structure as entity properties (GraphEdgeProperty is an alias for GraphNodeProperty). This is useful for relationships that carry data of their own.
// Example: an ENROLLED_IN relationship with properties
{
id: "edge-uuid",
source: "student-node-id",
target: "course-node-id",
label: "ENROLLED_IN",
cardinality: "N:M",
directed: true,
properties: [
{ name: "enrollmentDate", type: "date", required: true },
{ name: "grade", type: "string", nullable: true },
{ name: "status", type: "enum", enumValues: ["active", "completed", "withdrawn"] }
]
}
FK-generated Edges
Foreign key properties on entities optionally generate visible edges. When an entity property has keyRole: "foreign" and its fkResolution has showEdge: true, the editor creates an edge between the source entity and the resolved target entity.
Directed vs Undirected Edges
Edges default to directed (directed: true), meaning they have a source and a target with an arrowhead indicating direction. Setting directed: false removes the directional arrowhead, representing a bidirectional or symmetric relationship. Cardinality decorations still appear on both ends regardless of directionality.
Composite Constraints
Beyond single-property constraints, the model supports composite constraints that span multiple properties on a node label. These are used for composite indexes and multi-column uniqueness constraints.
interface GraphCompositeConstraint {
id: string; // Unique ID
type: 'index' | 'unique'; // Constraint type
nodeLabel: string; // Which entity label this applies to
propertyNames: string[]; // Ordered list of property names
name?: string; // Optional human-readable name
}