---
title: "Record links | SurrealDB University"
description: "Record links. A chapter of SurrealDB Fundamentals, a hands-on course with runnable examples."
url: https://surrealdb.com/learn/fundamentals/relationships/record-links
---

[Back to Courses](https://surrealdb.com/learn)

Course chapters

[SurrealDB Fundamentals](https://surrealdb.com/learn/fundamentals) [Introduction](https://surrealdb.com/learn/fundamentals) [Welcome to SurrealDB University](https://surrealdb.com/learn/fundamentals/intro/welcome) [Intro to SurrealDB](https://surrealdb.com/learn/fundamentals/intro/surrealdb) [Why SurrealQL is SQL-like](https://surrealdb.com/learn/fundamentals/intro/surrealql) [Part 1: Schemaless CRUD](https://surrealdb.com/learn/fundamentals/schemaless) [Introduction](https://surrealdb.com/learn/fundamentals/schemaless) [Record IDs](https://surrealdb.com/learn/fundamentals/schemaless/record-ids) [Inserting data](https://surrealdb.com/learn/fundamentals/schemaless/inserting-data) [Reading data](https://surrealdb.com/learn/fundamentals/schemaless/reading-data) [Updating data](https://surrealdb.com/learn/fundamentals/schemaless/updating-data) [Deleting data](https://surrealdb.com/learn/fundamentals/schemaless/deleting-data) [Part 2: Adding relationships](https://surrealdb.com/learn/fundamentals/relationships) [Introduction](https://surrealdb.com/learn/fundamentals/relationships) [Graph relations](https://surrealdb.com/learn/fundamentals/relationships/graph-relations) [Record links](https://surrealdb.com/learn/fundamentals/relationships/record-links) [Relational style joins](https://surrealdb.com/learn/fundamentals/relationships/relational-style) [Part 3: Making it schemafull](https://surrealdb.com/learn/fundamentals/schemafull) [Introduction](https://surrealdb.com/learn/fundamentals/schemafull) [Define tables, views and changefeeds](https://surrealdb.com/learn/fundamentals/schemafull/define-table) [Define fields, constraints and assertions](https://surrealdb.com/learn/fundamentals/schemafull/define-fields) [Schemafull CRUD](https://surrealdb.com/learn/fundamentals/schemafull/schemafull-crud) [Part 4: Making it secure](https://surrealdb.com/learn/fundamentals/security) [Introduction](https://surrealdb.com/learn/fundamentals/security) [Authentication](https://surrealdb.com/learn/fundamentals/security/authentication) [Query capabilities](https://surrealdb.com/learn/fundamentals/security/query-capabilities) [Part 5: Making it performant](https://surrealdb.com/learn/fundamentals/performance) [Introduction](https://surrealdb.com/learn/fundamentals/performance) [Indexing & data model considerations](https://surrealdb.com/learn/fundamentals/performance/index-data-model) [Deployment & storage layer considerations](https://surrealdb.com/learn/fundamentals/performance/deployment-storage) [Completion](https://surrealdb.com/learn/fundamentals/completion) Certification Pending completion

# Record links

The second relationship type we'll be exploring is record links. We'll go through:

- How record links work
- How to practically model our data using record links
- How to use record links in our CRUD operations

## How record links work

A record link is simply an external record ID that is directly embedded in another record, similar to a foreign key in relational databases.

However, record links are different from foreign keys because they are record IDs that directly access the underlying key-value storage engine.

This allows us to traverse from record to record without needing to run a table scan query because the table and key of the ID are already known. It directly fetches the record instead of scanning for a matching needle in a haystack, like in traditional SQL joins.

## Modelling our data using record links

In the previous lesson, we created a primary relationship based on the major actions a person using our e-commerce store would take: wishlist, cart, order and review.

Now we are moving on to secondary relationships. Which are:

- Making a one-way relationship from the `product` to the `seller`.
- Making bidirectional relationships to and from `address_history` and `payment_details` to the `person`.

One important thing to note before moving on, is that while we're talking about primary and secondary relationships here, you can model your data completely using graph relations or using record links.

It all depends on your needs, this is just one recommended way of doing things.

### One-way record links

```
UPDATE product SET seller = seller:surrealdb;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

To make a one-way relationship from the `product` to the `seller`, we can set the record ID `seller:surrealdb` as the value of the `seller` field for all the records in our `product` table.

That way, we can link every product to information about the seller of that product. Since the Surreal Deal Store is based on our swag store, [SurrealDB.store](https://surrealdb.store/), the seller will always be SurrealDB. This is why we've created this one-to-many relationship.

An important thing to notice here is that we haven't created the `seller` table yet, but were still able to insert the `seller` record ID into the product table because there are no foreign key constraints for record links.

Let's therefore quickly create the `seller` table such that our product record link will actually go somewhere.

```
CREATE seller:surrealdbSET name = "SurrealDB", email = "education@surrealdb.com"
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

### Bidirectional record links

Record links don't hold any metadata like graph links do, but they can be queried bidirectionally if you want. The way you do this is by defining them as a field of type `record`, followed by the `REFERENCE` clause. They look like this, and are at the very top of the dataset for this part of the course. This is our first look at a `DEFINE` statement, which we will look a lot more at in the next section.

```surql
DEFINE FIELD person ON TABLE address_history TYPE record<person> REFERENCE;
DEFINE FIELD person ON TABLE payment_details TYPE record<person> REFERENCE;
```

With those definitions set up, adding record links from `address_history` and `payment_details` to the `person` will let them be queried on either side. We'll look at that in a second.

```
CREATE address_history:ulid(), payment_details:ulid()SET person = person:01GFFXDCG89SAR3WM2SDV2E1RA;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

You could also just add a record link manually if you want, but as you can see it is more work.

```
UPDATE person:01GFFXDCG89SAR3WM2SDV2E1RA MERGE {  address_history: address_history:01HCWCEB1R8Y499XJYPVWE04RX,  payment_details: payment_details:01FTZ3MR7095CRDT1A04NNRQ6H};
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

When querying an incoming record link you use this `<~` operator. It's similar to graph syntax except that it uses a `~` (a tilde or a "squiggly").

Here are two queries returning a single record that includes the record link to the person to get the person's name.

```
SELECT   addresses.country,  person.nameFROM address_history LIMIT 1;SELECT  stored_cards.expiry_year,  person.nameFROM payment_details LIMIT 1;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

And now here are two similar queries that turn it around. This time, we are querying from the `person`, then using `<~address_history` or `<~payment_details` to access those linking records from the other end.

```
SELECT   name,  <~address_history.addresses.country AS countriesFROM person LIMIT 1;SELECT   name,  <~payment_details.stored_cards.expiry_year AS expiry_yearsFROM person LIMIT 1;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

## Record links: CRUD operations

We've already covered how to create record links, let's now explore how to use them in the rest of our CRUD operations.

```
-- Selecting the current address from the person tableSELECT    person.address.address_line_1  AS current_address,    addresses[0].address_line_1 AS previous_addressFROM address_history:01HCWCEB1R8Y499XJYPVWE04RX;-- Adding the current address to the address_history tableUPDATE address_history:01HCWCEB1R8Y499XJYPVWE04RXSET addresses += person.address;-- Deleting the address history from Leoma-- Use RETURN BEFORE to return the record info-- from before deletionDELETE address_historyWHERE person.name = "Leoma Santiago" RETURN BEFORE;
```

![Surrealist Icon](https://surrealdb.com/assets/static/fdfe2c20f5941d5e.D0guSOhZ.webp) Run Query

As these examples show, you can use record links in CRUD operations in the same way as you would, if it was all embedded in the same record, using the dot and bracket notation.

## Summary

Now that we've interlinked our knowledge of record links, let's summarise what we've learned.

Record links:

- Are external record IDs that are directly embedded in other records, similar to foreign keys in relational databases, but allowing us to traverse from record to record without needing to run a table scan query.
- Require no special statement to create; inserting record IDs into other records will link them together.
- Only work in one direction by default. But if you define one with the `REFERENCE` keyword, you can query from the other direction as well.

You can use record links in CRUD operations in the same way as you would, if it was all embedded in the same record, using the dot and bracket notation.

That's everything about record links, I'll see you in the next lesson, where we'll explore relational style joins.

Previous

Graph relations

[Previous](https://surrealdb.com/learn/fundamentals/relationships/graph-relations)

Next lesson

Relational style joins

[Next lesson](https://surrealdb.com/learn/fundamentals/relationships/relational-style)

```json
{"@context":"https://schema.org","@type":"Course","name":"SurrealDB Fundamentals","description":"The most efficient way to learn SurrealDB through guided hands-on learning","url":"https://surrealdb.com/learn/fundamentals","inLanguage":"en","isAccessibleForFree":false,"provider":{"@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com"},"hasPart":[{"@type":"LearningResource","name":"SurrealDB Fundamentals","url":"https://surrealdb.com/learn/fundamentals"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals"},{"@type":"LearningResource","name":"Welcome to SurrealDB University","url":"https://surrealdb.com/learn/fundamentals/intro/welcome"},{"@type":"LearningResource","name":"Intro to SurrealDB","url":"https://surrealdb.com/learn/fundamentals/intro/surrealdb"},{"@type":"LearningResource","name":"Why SurrealQL is SQL-like","url":"https://surrealdb.com/learn/fundamentals/intro/surrealql"},{"@type":"LearningResource","name":"Part 1: Schemaless CRUD","url":"https://surrealdb.com/learn/fundamentals/schemaless"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/schemaless"},{"@type":"LearningResource","name":"Record IDs","url":"https://surrealdb.com/learn/fundamentals/schemaless/record-ids"},{"@type":"LearningResource","name":"Inserting data","url":"https://surrealdb.com/learn/fundamentals/schemaless/inserting-data"},{"@type":"LearningResource","name":"Reading data","url":"https://surrealdb.com/learn/fundamentals/schemaless/reading-data"},{"@type":"LearningResource","name":"Updating data","url":"https://surrealdb.com/learn/fundamentals/schemaless/updating-data"},{"@type":"LearningResource","name":"Deleting data","url":"https://surrealdb.com/learn/fundamentals/schemaless/deleting-data"},{"@type":"LearningResource","name":"Part 2: Adding relationships","url":"https://surrealdb.com/learn/fundamentals/relationships"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/relationships"},{"@type":"LearningResource","name":"Graph relations","url":"https://surrealdb.com/learn/fundamentals/relationships/graph-relations"},{"@type":"LearningResource","name":"Record links","url":"https://surrealdb.com/learn/fundamentals/relationships/record-links"},{"@type":"LearningResource","name":"Relational style joins","url":"https://surrealdb.com/learn/fundamentals/relationships/relational-style"},{"@type":"LearningResource","name":"Part 3: Making it schemafull","url":"https://surrealdb.com/learn/fundamentals/schemafull"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/schemafull"},{"@type":"LearningResource","name":"Define tables, views and changefeeds","url":"https://surrealdb.com/learn/fundamentals/schemafull/define-table"},{"@type":"LearningResource","name":"Define fields, constraints and assertions","url":"https://surrealdb.com/learn/fundamentals/schemafull/define-fields"},{"@type":"LearningResource","name":"Schemafull CRUD","url":"https://surrealdb.com/learn/fundamentals/schemafull/schemafull-crud"},{"@type":"LearningResource","name":"Part 4: Making it secure","url":"https://surrealdb.com/learn/fundamentals/security"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/security"},{"@type":"LearningResource","name":"Authentication","url":"https://surrealdb.com/learn/fundamentals/security/authentication"},{"@type":"LearningResource","name":"Query capabilities","url":"https://surrealdb.com/learn/fundamentals/security/query-capabilities"},{"@type":"LearningResource","name":"Part 5: Making it performant","url":"https://surrealdb.com/learn/fundamentals/performance"},{"@type":"LearningResource","name":"Introduction","url":"https://surrealdb.com/learn/fundamentals/performance"},{"@type":"LearningResource","name":"Indexing \u0026 data model considerations","url":"https://surrealdb.com/learn/fundamentals/performance/index-data-model"},{"@type":"LearningResource","name":"Deployment \u0026 storage layer considerations","url":"https://surrealdb.com/learn/fundamentals/performance/deployment-storage"},{"@type":"LearningResource","name":"Completion","url":"https://surrealdb.com/learn/fundamentals/completion"}]}
```

```json
{"@context":"https://schema.org","@type":"LearningResource","name":"Record links","description":"Record links","url":"https://surrealdb.com/learn/fundamentals/relationships/record-links","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"SurrealDB Fundamentals","url":"https://surrealdb.com/learn/fundamentals"},"position":16}
```

```json
{"@context":"https://schema.org","@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com","logo":"https://surrealdb.com/assets/static/logo.BG7_TG2b.svg","description":"SurrealDB is the unified data layer for AI. A multi-model database for documents, graphs, vectors, and time-series.","foundingDate":"2022","hasCertification":[{"@type":"Certification","name":"SOC 2 Type 2"},{"@type":"Certification","name":"GDPR"},{"@type":"Certification","name":"Cyber Essentials Plus"},{"@type":"Certification","name":"ISO 27001"}],"owns":[{"@type":"SoftwareApplication","name":"SurrealDB","url":"https://surrealdb.com/surrealdb"},{"@type":"SoftwareApplication","name":"Agent Memory","url":"https://surrealdb.com/agent-memory"}],"knowsAbout":["multi-model databases","document databases","graph databases","vector search","time-series databases","SurrealQL","Agent Memory","real-time databases","embedded databases","context layer","graph ontology","distributed database","knowledge graphs","distributed transaction protocols","highly-scalable databases"],"sameAs":["https://www.wikidata.org/wiki/Q124316308","https://github.com/surrealdb/surrealdb","https://twitter.com/surrealdb","https://www.youtube.com/@surrealdb","https://www.linkedin.com/company/surrealdb","https://discord.gg/surrealdb","https://www.reddit.com/r/surrealdb","https://www.instagram.com/surrealdb","https://medium.com/surrealdb","https://dev.to/surrealdb"]}
```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://surrealdb.com"},{"@type":"ListItem","position":2,"name":"Learn","item":"https://surrealdb.com/learn"},{"@type":"ListItem","position":3,"name":"Record links","item":"https://surrealdb.com/learn/fundamentals/relationships/record-links"}]}
```
