Jun 2, 2025
In a recent SurrealDB Stream, we cracked open a foundational part of SurrealDB’s power: relationship modelling. From traditional record-to-record links to bidirectional references and Graph Edge metadata, we explored the many ways you can model connected data - clearly, scalably, and with performance in mind.
Here’s what we covered, broken out by relationship type.
One of SurrealDB’s most powerful features is its ability to connect records without the need for JOINs or intermediate tables. At the heart of this is the Record Link: a direct pointer from one record to another using the built-in table:id
syntax.
CREATE person:jaime SET friends = [person:tobie, person:simon]; SELECT friends.name FROM person:jaime;
This isn’t a foreign key - it’s better. Since Record IDs are first-class citizens in SurrealQL, SurrealDB can fetch remote data directly from disk without scanning tables. And when a record includes another as a field, the engine can automatically fetch nested records, even several layers deep:
SELECT friends.friends.friends.name FROM person:tobie;
However, keep in mind that these links are static: if a linked record is deleted or modified, the parent record won’t update automatically. For true referential integrity, consider using Graph Edges or Record References.
Available since SurrealDB 2.2.0, Record References allow you to automatically track reverse relationships between records - no JOINs or custom queries needed. But keep in mind: references are still an experimental feature, disabled by default.
surreal start --allow-experimental record_references
Once enabled, you can define forward and reverse fields like this:
DEFINE FIELD comics ON person TYPE option<array<record<comic_book>>> REFERENCE; DEFINE FIELD owners ON comic_book TYPE references<person, comics>;
Now when a person adds a comic to their comics
list, that comic’s owners
field automatically reflects the relationship.
Want to dynamically inspect references at query time? Use .refs()
:
comic_book:one.refs('person', 'comics');
You can even control what happens when referenced records are deleted using ON DELETE
clauses:
IGNORE
(default) - do nothingUNSET
- remove deleted referencesCASCADE
- delete dependent recordsREJECT
- block deletionTHEN { ... }
- run custom logicRecord References combine flexibility with schema-driven control - ideal when you need reverse visibility without building manual joins.
A Graph Edge in SurrealDB is a full-fledged record - stored in its own table - that connects two records and can hold metadata describing their relationship.
RELATE person:alex->follows->person:tobie SET followed_at = "2024-04-01", strength = "high";
Unlike Record Links, Graph Edges:
Graph Edges are especially useful when:
TYPE RELATION
.friends_with
using <->
.DEFINE TABLE likes TYPE RELATION IN person OUT blog_post
.Use Graph Edges when your relationships need stories: metadata, directionality, and multi-hop traversal - all native to SurrealQL.
Model your data the way you think: directly, flexibly, and with full graph awareness.
Check out the SurrealDB Fundamentals course to learn more about data modelling.
🎥 Watch the full stream: SurrealDB Stream #29: Simplify Graph Edges with Record References.
company
May 23, 2025
tutorials
Jun 3, 2025