Relationships
Model 1:1, 1:N and many-to-many links in SurrealQL, and pull them into a query with .related().
A relationship is a field of type record<table>. Declare it in the schema and the client can
traverse it in a single query with .related(). No joins, no second round trip.
thread.author comes back as a fully typed User, not an id, and the query stays live: editing the
author’s username updates every thread row that renders it.
One-to-one
A user has exactly one profile. Put a record<profile> field on user. Add the reverse field only
if you also need to traverse the other direction.
One-to-many
A thread has many comments. The rule is the same as in a relational database: the child holds the
reference. Put record<thread> on comment.
Query it from either end: from the child with .related('thread'), or from the parent by filtering
the child table on the parent id.
Keeping a mirror array<record<comment>> on the parent is optional and costs you a write on every
insert. Filter the child table instead unless you specifically need the ordered array.
Many-to-many
For users liking posts, or posts having tags, use a relation table, a table that stores graph edges and can carry its own fields.
Because the edge is a table, anything you’d put on a row works on it: timestamps, a rating, a
permission clause. Create edges with RELATE.
The @parent descriptor
When a record<...> field always points at the acting user, mark it -- @parent. Sp00ky fills it
from the auth context on write, so client code can never spoof it.
See Define your schema for the full descriptor list, and Reactive queries for the querying side.