Skip to content

Commit

Permalink
Add two exampes of auto-incrementing IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
Dhghomon committed Dec 13, 2024
1 parent 1547694 commit 4b6c777
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion src/content/doc-surrealql/datamodel/ids.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ An example of a record ID can look like this: `table:record_identifier`.

## Types of Record IDs

Record IDs can be constructed using a number of different types of values, including text, numbers, objects, and arrays. For example, by default when you [create a table](/docs/surrealql/statements/create), `create internet`, a random id is assigned. This differs from the traditional default of auto-increment or serial IDs you might be used to.
Record IDs can be constructed using a number of different types of values, including text, numbers, objects, and arrays. For example, by default when you [create a table](/docs/surrealql/statements/create), `create internet`, a random id is assigned. This differs from the traditional default of auto-increment or serial IDs many developers are used to.


> [!NOTE]
Expand Down Expand Up @@ -214,6 +214,37 @@ FROM { temps: [-5, 8, 9] };
]
```

### Auto-incrementing IDs

While SurrealDB does not use auto-incrementing IDs, this can be achieved in a number of ways. One is to use the [`record::id()`](/docs/surrealql/functions/database/record#recordid) function on the latest record, which returns the latter part of a record ID (the '1' in the record ID `person:1`). This can then be followed up with the [`type::thing()`](/docs/surrealql/functions/database/type#typething) function to create a new record ID.

```surql
CREATE person:1, person:2;
LET $latest = SELECT VALUE id FROM ONLY person ORDER BY id DESC LIMIT 1;
CREATE type::thing("person", $latest.id() + 1);
```

When dealing with a large number of records, a more performant option is to create a separate record that holds a single value representing the latest ID. An [`UPSERT`](/docs/surrealql/statements/upsert) statement is best here, which will allow the counter to be initialized if it does not yet exist, and updated otherwise. This is best done [inside a manual transaction](/docs/surrealql/statements/begin) so that the latest ID will be rolled back if any failures occur when creating the next record.

```surql
BEGIN TRANSACTION;
UPSERT person_id:counter SET num += 1;
-- Creates a person:1
CREATE type::thing("person", person_id:counter.num);
COMMIT TRANSACTION;
BEGIN TRANSACTION;
-- Latest ID is now 2
UPSERT person_id:counter SET num += 1;
-- Whoops, invalid datetime format
-- Transaction fails and all changes are rolled back
CREATE type::thing("person", person_id:counter.num) SET created_at = <datetime>'2025_01+01';
COMMIT TRANSACTION;
-- Latest ID is still 1
RETURN person_id:counter.num;
```

## Learn more

Learn more about Record IDs [in this blogpost](https://surrealdb.com/blog/the-life-changing-magic-of-surrealdb-record-ids#the-performance-at-scale) and on this [youtube video](https://www.youtube.com/watch?v=c0cqmWRYP8c).

0 comments on commit 4b6c777

Please sign in to comment.