---
title: "23: Adding and improving data | SurrealDB University"
description: "Adding and improving data. A step in the guided Tour of SurrealDB, with examples you can run as you read."
url: https://surrealdb.com/learn/tour/page-23
---

![Course content preview](https://surrealdb.com/assets/static/town.D95IYf2V.avif)

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

Course chapters

[Welcome to the Tour of SurrealDB!](https://surrealdb.com/learn/tour) [1: Connecting to a database](https://surrealdb.com/learn/tour/page-01) [2: Creating records](https://surrealdb.com/learn/tour/page-02) [3: Using the ONLY keyword](https://surrealdb.com/learn/tour/page-03) [4: Non-ASCII record IDs](https://surrealdb.com/learn/tour/page-04) [5: Parentheses, indexing, and fields](https://surrealdb.com/learn/tour/page-05) [6: Deleting records](https://surrealdb.com/learn/tour/page-06) [7: Field order in objects](https://surrealdb.com/learn/tour/page-07) [8: Tips when selecting records](https://surrealdb.com/learn/tour/page-08) [9: Casting and aliases](https://surrealdb.com/learn/tour/page-09) [10: Affixes](https://surrealdb.com/learn/tour/page-10) [11: Updating records](https://surrealdb.com/learn/tour/page-11) [12: Linking records](https://surrealdb.com/learn/tour/page-12) [13: Viewing the database as a whole](https://surrealdb.com/learn/tour/page-13) [14: Schemafull and schemaless](https://surrealdb.com/learn/tour/page-14) [15: Viewing the schema](https://surrealdb.com/learn/tour/page-15) [16: Literal types and assertions](https://surrealdb.com/learn/tour/page-16) [17: INSERT and using JSON](https://surrealdb.com/learn/tour/page-17) [18: FOR loops](https://surrealdb.com/learn/tour/page-18) [19: Basic graph relations](https://surrealdb.com/learn/tour/page-19) [20: Creating graph edges](https://surrealdb.com/learn/tour/page-20) [21: Querying graph relations](https://surrealdb.com/learn/tour/page-21) [22: Graph relations at greater depth](https://surrealdb.com/learn/tour/page-22) [23: Adding and improving data](https://surrealdb.com/learn/tour/page-23) [24: Defining events](https://surrealdb.com/learn/tour/page-24) [25: Defining indexes](https://surrealdb.com/learn/tour/page-25) [26: Improving the schema](https://surrealdb.com/learn/tour/page-26) [27: Visualising graph paths](https://surrealdb.com/learn/tour/page-27) [28: Recursive queries: setup](https://surrealdb.com/learn/tour/page-28) [29: Recursive queries](https://surrealdb.com/learn/tour/page-29) [30: More on recursive queries](https://surrealdb.com/learn/tour/page-30) [31: AI vector search](https://surrealdb.com/learn/tour/page-31) [Done the tour!](https://surrealdb.com/learn/tour/page-32)

# 23: Adding and improving data

The library needs some customers too, so we'll add them. We will use a query that is similar to one we used before: create some `person` records, and relate them to the library.

However, this time we will add three automatically generated fields to the `customer_of` table to help keep track of customer histories. They all use a clause called [`VALUE`](https://surrealdb.com/docs/reference/query-language/statements/define/field#using-the-value-clause-to-set-a-fields-value), but in different ways.

The first statement is for when the account is created. Its value is `time::now()` (the time when the operation is performed), and it is followed by `READONLY` because it should never be changed.

```surql
/**
[test]

[[test.results]]
value = "NONE"

*/

DEFINE FIELD account_created ON TABLE customer_of VALUE time::now() READONLY;
```

The second is called `last_updated`. It also takes a value of `time::now()`. Anything with a `VALUE` clause will be calculated when a record is created or updated, but not when it is simply read.

```surql
/**
[test]

[[test.results]]
value = "NONE"

*/

DEFINE FIELD last_updated ON TABLE customer_of VALUE time::now();
```

The last field is called `customer_for`, which shows how long a person has been a customer. This time the field name will be followed by something called a `COMPUTED` field, which holds an expression that is never stored but calculated every time a field is read. In this case, `time::now() - account_created` will do the job.

```surql
DEFINE FIELD customer_for
  ON TABLE customer_of
  COMPUTED time::now() - account_created;
```

With these fields defined, we can start creating some customers. Once they are created, we will do a query on one of the `customer_of` tables, use a [`SLEEP`](https://surrealdb.com/docs/reference/query-language/statements/sleep) statement to make the database sleep for one second, and then query the table again.

```
FOR $data IN [  { age: 15, name: 'Archie Andrews'   },  { age: 15, name: 'Veronica Lodge'   },  { age: 15, name: 'Betty Cooper'     },  { age: 15, name: 'Jughead Jones'    },  { age: 15, name: 'Reggie Mantle'    },  { age: 50, name: 'Hiram P. Lodge'   },    { age: 55, name: 'Geraldine Grundy' },  { age: 65, name: 'Waldo Weatherbee' }] {    LET $person = CREATE ONLY person SET        name = $data.name,        age = $data.age;    RELATE $person->customer_of->place:surreal_library;};SELECT   out.name AS customer_of,  account_created,  customer_for,  last_updatedFROM customer_of LIMIT 1;SLEEP 1s;SELECT   out.name AS customer_of,  account_created,  customer_for,  last_updatedFROM customer_of LIMIT 1;
```

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

You can see that the `customer_for` field will always be a greater number every time you select it, as more time will have passed since the last query.

Response

```surql
-------- Query --------

[
  {
    account_created: d'2025-03-19T05:26:14.912Z',
    customer_for: 1ms,
    customer_of: 'Surreal Library',
    last_updated: d'2025-03-19T05:26:14.912Z'
  }
]

-------- Query --------

[
  {
    account_created: d'2025-03-19T05:26:14.912Z',
    customer_for: 1s3ms,
    customer_of: 'Surreal Library',
    last_updated: d'2025-03-19T05:26:14.912Z'
  }
]
```

The library also needs some books. To keep things short, our library will have just the eight most sold books of all time. The data for each one looks like this.

```surql
{
    author: 'Charles Dickens',
    english_title: 'A Tale of Two Cities',
    language: 'en',
    published: '1859-11-26',
    title: 'A Tale of Two Cities'
}
```

When inserting, we can cast the `published` field as a `datetime` instead of a simple `string`. This will make it possible to use [datetime functions](https://surrealdb.com/docs/reference/query-language/functions/database-functions/time) and [duration functions](https://surrealdb.com/docs/reference/query-language/functions/database-functions/duration), or operators like `-` or `+`.

Here are two examples of the convenience you get when using the `datetime` and `duration` types as opposed to simple strings.

```
-- Time since the traditional founding of Rome, 753 BCd'2025-01-01' - d'-0753-01-01';-- Same time in hoursduration::hours(d'2025-01-01' - d'-0753-01-01');
```

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

Response

```surql
-------- Query --------

2779y44w1d

-------- Query --------

24351456
```

For each of these books in the next `FOR` loop, we will do the following:

- Since the `author` field is a person's name, we'll use it to create a `person`. The output of the `CREATE` statement will go in a parameter called `$author`.
- Create the book, capturing the output in the parameter `$book`.
- Relate the author to the book with `$person->wrote->$book`, and the book to the library with `RELATE place:surreal_library->has->$book`.

```
FOR $data IN [  {    author: 'Charles Dickens',    english_title: 'A Tale of Two Cities',    language: 'en',    published: "1859-11-26",    title: 'A Tale of Two Cities'  },    {        author: "Antoine de Saint-Exupéry",        english_title: "The Little Prince",        language: "fr",        published: "1943-04-15",        title: "Le Petit Prince"    },  {    author: 'Paulo Coelho',    english_title: 'The Alchemist',    language: 'pt',    published: "1988-03-01",    title: 'O Alquimista'  },  {    author: 'J.K. Rowling',    english_title: "Harry Potter and the Philosopher's Stone",    language: 'en',    published: "1997-06-26",    title: "Harry Potter and the Philosopher's Stone"  },  {    author: 'Agatha Christie',    english_title: 'And Then There Were None',    language: 'en',    published: "1939-11-06",    title: 'And Then There Were None'  },  {    author: 'Cao Xueqin',    english_title: 'Dream of the Red Chamber',    language: 'zh',    published: "1791-03-01",    title: '紅樓夢'  },  {    author: 'J.R.R. Tolkien',    english_title: 'The Hobbit',    language: 'en',    published: "1937-09-21",    title: 'The Hobbit'  },  {    author: 'Lewis Carroll',    english_title: "Alice's Adventures in Wonderland",    language: 'en',    published: "1865-07-04",    title: "Alice's Adventures in Wonderland"  }] {    -- Create the author for each book, return just the object    LET $author = CREATE ONLY person SET        name = $data.author;    -- Create the book, cast 'published' field from string to datetime    LET $book = CREATE ONLY book SET        author = $data.author,        english_title = $data.english_title,        language = $data.language,        published = <datetime>$data.published,        title = $data.title;    -- Connect the author to the book    RELATE $author->wrote->$book;    -- Give the book to the library    RELATE place:surreal_library->has->$book;};
```

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

With the authors and books in the library, we can do more graph queries. Let's try two of them here.

Which books have been written by three sample authors in the database? The `->wrote->book.title` path will show this. We can add `WHERE ->wrote->book` too to make it only return people that wrote books.

```
SELECT   name AS author,   ->wrote->book.title AS booksFROM person  WHERE ->wrote->book  LIMIT 3;
```

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

Response

```surql
[
  {
    author: 'J.R.R. Tolkien',
    books: [
      'The Hobbit'
    ]
  },
  {
    author: 'Agatha Christie',
    books: [
      'And Then There Were None'
    ]
  },
  {
    author: 'Lewis Carroll',
    books: [
      "Alice's Adventures in Wonderland"
    ]
  }
]
```

What are the names of the places and the books that they have? The `->has.out.title` path will show this.

```
SELECT   name,   ->has.out.title AS booksFROM place;
```

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

Response

```surql
[
  {
    books: [
      'The Hobbit',
      'And Then There Were None',
      'A Tale of Two Cities',
      "Harry Potter and the Philosopher's Stone",
      'Le Petit Prince',
      "Alice's Adventures in Wonderland",
      '紅樓夢',
      'O Alquimista'
    ],
    name: 'Surreal Library'
  }
]
```

Previous

22: Graph relations at greater depth

[Previous](https://surrealdb.com/learn/tour/page-22)

Next lesson

24: Defining events

[Next lesson](https://surrealdb.com/learn/tour/page-24)

```json
{"@context":"https://schema.org","@type":"Course","name":"Welcome to the Tour of SurrealDB!","description":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour","inLanguage":"en","isAccessibleForFree":true,"provider":{"@type":"Organization","name":"SurrealDB","url":"https://surrealdb.com"},"hasPart":[{"@type":"LearningResource","name":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour"},{"@type":"LearningResource","name":"1: Connecting to a database","url":"https://surrealdb.com/learn/tour/page-01"},{"@type":"LearningResource","name":"2: Creating records","url":"https://surrealdb.com/learn/tour/page-02"},{"@type":"LearningResource","name":"3: Using the ONLY keyword","url":"https://surrealdb.com/learn/tour/page-03"},{"@type":"LearningResource","name":"4: Non-ASCII record IDs","url":"https://surrealdb.com/learn/tour/page-04"},{"@type":"LearningResource","name":"5: Parentheses, indexing, and fields","url":"https://surrealdb.com/learn/tour/page-05"},{"@type":"LearningResource","name":"6: Deleting records","url":"https://surrealdb.com/learn/tour/page-06"},{"@type":"LearningResource","name":"7: Field order in objects","url":"https://surrealdb.com/learn/tour/page-07"},{"@type":"LearningResource","name":"8: Tips when selecting records","url":"https://surrealdb.com/learn/tour/page-08"},{"@type":"LearningResource","name":"9: Casting and aliases","url":"https://surrealdb.com/learn/tour/page-09"},{"@type":"LearningResource","name":"10: Affixes","url":"https://surrealdb.com/learn/tour/page-10"},{"@type":"LearningResource","name":"11: Updating records","url":"https://surrealdb.com/learn/tour/page-11"},{"@type":"LearningResource","name":"12: Linking records","url":"https://surrealdb.com/learn/tour/page-12"},{"@type":"LearningResource","name":"13: Viewing the database as a whole","url":"https://surrealdb.com/learn/tour/page-13"},{"@type":"LearningResource","name":"14: Schemafull and schemaless","url":"https://surrealdb.com/learn/tour/page-14"},{"@type":"LearningResource","name":"15: Viewing the schema","url":"https://surrealdb.com/learn/tour/page-15"},{"@type":"LearningResource","name":"16: Literal types and assertions","url":"https://surrealdb.com/learn/tour/page-16"},{"@type":"LearningResource","name":"17: INSERT and using JSON","url":"https://surrealdb.com/learn/tour/page-17"},{"@type":"LearningResource","name":"18: FOR loops","url":"https://surrealdb.com/learn/tour/page-18"},{"@type":"LearningResource","name":"19: Basic graph relations","url":"https://surrealdb.com/learn/tour/page-19"},{"@type":"LearningResource","name":"20: Creating graph edges","url":"https://surrealdb.com/learn/tour/page-20"},{"@type":"LearningResource","name":"21: Querying graph relations","url":"https://surrealdb.com/learn/tour/page-21"},{"@type":"LearningResource","name":"22: Graph relations at greater depth","url":"https://surrealdb.com/learn/tour/page-22"},{"@type":"LearningResource","name":"23: Adding and improving data","url":"https://surrealdb.com/learn/tour/page-23"},{"@type":"LearningResource","name":"24: Defining events","url":"https://surrealdb.com/learn/tour/page-24"},{"@type":"LearningResource","name":"25: Defining indexes","url":"https://surrealdb.com/learn/tour/page-25"},{"@type":"LearningResource","name":"26: Improving the schema","url":"https://surrealdb.com/learn/tour/page-26"},{"@type":"LearningResource","name":"27: Visualising graph paths","url":"https://surrealdb.com/learn/tour/page-27"},{"@type":"LearningResource","name":"28: Recursive queries: setup","url":"https://surrealdb.com/learn/tour/page-28"},{"@type":"LearningResource","name":"29: Recursive queries","url":"https://surrealdb.com/learn/tour/page-29"},{"@type":"LearningResource","name":"30: More on recursive queries","url":"https://surrealdb.com/learn/tour/page-30"},{"@type":"LearningResource","name":"31: AI vector search","url":"https://surrealdb.com/learn/tour/page-31"},{"@type":"LearningResource","name":"Done the tour!","url":"https://surrealdb.com/learn/tour/page-32"}]}
```

```json
{"@context":"https://schema.org","@type":"LearningResource","name":"23: Adding and improving data","description":"Adding and improving data","url":"https://surrealdb.com/learn/tour/page-23","learningResourceType":"lesson","isPartOf":{"@type":"Course","name":"Welcome to the Tour of SurrealDB!","url":"https://surrealdb.com/learn/tour"},"position":24}
```

```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":"Page 23","item":"https://surrealdb.com/learn/tour/page-23"}]}
```
