You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/current/_includes/v25.3/faq/auto-generate-unique-ids.md
+15-1Lines changed: 15 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,14 @@
1
-
To auto-generate unique row identifiers, you can use the `gen_random_uuid()`, `uuid_v4()`, or `unique_rowid()`[functions]({% link {{ page.version.version }}/functions-and-operators.md %}#id-generation-functions).
1
+
To auto-generate unique row identifiers, you can use the following [functions]({% link {{ page.version.version }}/functions-and-operators.md %}#id-generation-functions):
2
+
3
+
-[Use `gen_random_uuid()`](#use-gen_random_uuid): Generates a UUIDv4 with `UUID` data type.
4
+
-[Use `uuid_v4()`](#use-uuid_v4): Generates a UUIDv4 with `BYTES` data type.
5
+
-[Use `unique_rowid()`](#use-unique_rowid): Generates a globally unique `INT` data type
6
+
7
+
{{site.data.alerts.callout_success}}
8
+
{% include {{ page.version.version }}/sql/use-uuidv4.md %}
9
+
{{site.data.alerts.end}}
10
+
11
+
#### Use `gen_random_uuid()`
2
12
3
13
To use the [`UUID`]({% link {{ page.version.version }}/uuid.md %}) column with the `gen_random_uuid()`[function]({% link {{ page.version.version }}/functions-and-operators.md %}#id-generation-functions) as the [default value]({% link {{ page.version.version }}/default-value.md %}):
4
14
@@ -34,6 +44,8 @@ SELECT * FROM users;
34
44
(3 rows)
35
45
~~~
36
46
47
+
#### Use `uuid_v4()`
48
+
37
49
Alternatively, you can use the [`BYTES`]({% link {{ page.version.version }}/bytes.md %}) column with the `uuid_v4()` function as the default value:
38
50
39
51
{% include_cached copy-clipboard.html %}
@@ -72,6 +84,8 @@ In either case, generated IDs will be 128-bit, sufficiently large to generate un
72
84
73
85
This approach has the disadvantage of creating a primary key that may not be useful in a query directly, which can require a join with another table or a secondary index.
74
86
87
+
#### Use `unique_rowid()`
88
+
75
89
If it is important for generated IDs to be stored in the same key-value range, you can use an [integer type]({% link {{ page.version.version }}/int.md %}) with the `unique_rowid()`[function]({% link {{ page.version.version }}/functions-and-operators.md %}#id-generation-functions) as the default value, either explicitly or via the [`SERIAL` pseudo-type]({% link {{ page.version.version }}/serial.md %}):
Copy file name to clipboardExpand all lines: src/current/v25.3/alter-table.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1852,7 +1852,7 @@ Suppose that you are storing the data for users of your application in a table c
1852
1852
);
1853
1853
~~~
1854
1854
1855
-
The primary key of this table is on the `name` column. This is a poor choice, as some users likely have the same name, and all primary keys enforce a `UNIQUE` constraint on row values of the primary key column. Per our [best practices]({% link {{ page.version.version }}/performance-best-practices-overview.md %}#use-functions-to-generate-unique-ids), you should instead use a `UUID` for single-column primary keys, and populate the rows of the table with generated, unique values.
1855
+
The primary key of this table is on the `name` column. This is a poor choice, as some users likely have the same name, and all primary keys enforce a `UNIQUE` constraint on row values of the primary key column. Per our [best practices]({% link {{ page.version.version }}/performance-best-practices-overview.md %}#use-functions-to-generate-unique-ids), you should instead use a [`UUID`]({% link {{ page.version.version }}/uuid.md %}) for single-column primary keys, and populate the rows of the table with generated, unique values.
1856
1856
1857
1857
You can add a column and change the primary key with a couple of `ALTER TABLE` statements:
Copy file name to clipboardExpand all lines: src/current/v25.3/create-sequence.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ The `CREATE SEQUENCE` [statement]({% link {{ page.version.version }}/sql-stateme
11
11
12
12
## Considerations
13
13
14
-
- Using a sequence is slower than [auto-generating unique IDs with the `gen_random_uuid()`, `uuid_v4()` or `unique_rowid()` built-in functions]({% link {{ page.version.version }}/sql-faqs.md %}#how-do-i-auto-generate-unique-row-ids-in-cockroachdb). Incrementing a sequence requires a write to persistent storage, whereas auto-generating a unique ID does not. Therefore, use auto-generated unique IDs unless an incremental sequence is preferred or required. For more information, see [Unique ID best practices]({% link {{ page.version.version }}/performance-best-practices-overview.md %}#unique-id-best-practices).
14
+
- Using a sequence is slower than [auto-generating unique IDs with the `gen_random_uuid()`, `uuid_v4()` or `unique_rowid()` built-in functions]({% link {{ page.version.version }}/sql-faqs.md %}#how-do-i-auto-generate-unique-row-ids-in-cockroachdb) and is likely to cause performance problems due to [hotspots]({% link {{ page.version.version }}/understand-hotspots.md %}). Incrementing a sequence requires a write to persistent storage, whereas auto-generating a unique ID does not. Therefore, use auto-generated unique IDs unless an incremental sequence is preferred or required. For more information, see [Unique ID best practices]({% link {{ page.version.version }}/performance-best-practices-overview.md %}#unique-id-best-practices).
15
15
- A column that uses a sequence can have a gap in the sequence values if a transaction advances the sequence and is then rolled back. Sequence updates are committed immediately and aren't rolled back along with their containing transaction. This is done to avoid blocking concurrent transactions that use the same sequence.
16
16
- {% include {{page.version.version}}/performance/use-hash-sharded-indexes.md %}
17
17
- By default, you cannot create sequences that are [owned by]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership) columns in tables in other databases. You can enable such sequence creation by setting the `sql.cross_db_sequence_owners.enabled`[cluster setting]({% link {{ page.version.version }}/cluster-settings.md %}) to `true`.
Copy file name to clipboardExpand all lines: src/current/v25.3/liquibase.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -332,7 +332,7 @@ Liquibase does not [retry transactions]({% link {{ page.version.version }}/trans
332
332
333
333
Suppose that you want to change the primary key of the `accounts` table from a simple, incrementing [integer]({% link {{ page.version.version }}/int.md %}) (in this case, `id`) to an auto-generated [UUID]({% link {{ page.version.version }}/uuid.md %}), to follow some [CockroachDB best practices]({% link {{ page.version.version }}/performance-best-practices-overview.md %}#unique-id-best-practices). You can make these changes to the schema by creating and executing an additional changeset:
334
334
335
-
1. Create a SQL file to add a new UUID-typed column to the table:
335
+
1. Create a SQL file to add a new [UUID]({% link {{ page.version.version }}/uuid.md %})-typed column to the table:
Copy file name to clipboardExpand all lines: src/current/v25.3/movr-flask-application.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -110,7 +110,7 @@ The `User` class has the following attributes:
110
110
111
111
-`__tablename__`, which holds the stored name of the table in the database. SQLAlchemy requires this attribute forall classes that map to tables.
112
112
- All of the other attributes of the `User`class (`id`, `city`, `first_name`, etc.), stored as`Column` objects. These attributes represent columns of the `users` table. The constructor for each `Column` takes the column data typeas its first argument, and then any additional arguments, such as`primary_key`.
113
-
- To help define column objects, SQLAlchemy also includes classes forSQL data types and column constraints. For the columns in this table, we use `UUID`and`String` data types.
113
+
- To help define column objects, SQLAlchemy also includes classes forSQL data types and column constraints. For the columns in this table, we use [`UUID`]({% link {{ page.version.version }}/uuid.md %})and`String` data types.
114
114
- The `__repr__` function, which defines the string representation of the object.
Copy file name to clipboardExpand all lines: src/current/v25.3/performance-best-practices-overview.md
+4-7Lines changed: 4 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -64,12 +64,7 @@ When a table is created, all columns are stored as a single column family. This
64
64
65
65
## Unique ID best practices
66
66
67
-
The best practices for generating unique IDs in a distributed database like CockroachDB are very different than for a legacy single-node database. Traditional approaches for generating unique IDs for legacy single-node databases include:
68
-
69
-
1. Using the [`SERIAL`]({% link {{ page.version.version }}/serial.md %}) pseudo-type for a column to generate random unique IDs. This can result in a performance bottleneck because IDs generated temporally near each other have similar values and are located physically near each other in a table's storage.
70
-
1. Generating monotonically increasing [`INT`]({% link {{ page.version.version }}/int.md %}) IDs by using transactions with roundtrip [`SELECT`]({% link {{ page.version.version }}/select-clause.md %})s, e.g., `INSERT INTO tbl (id, …) VALUES ((SELECT max(id)+1 FROM tbl), …)`. This has a **very high performance cost** since it makes all [`INSERT`]({% link {{ page.version.version }}/insert.md %}) transactions wait for their turn to insert the next ID. You should only do this if your application really does require strict ID ordering. In some cases, using [change data capture (CDC)]({% link {{ page.version.version }}/change-data-capture-overview.md %}) can help avoid the requirement for strict ID ordering. If you can avoid the requirement for strict ID ordering, you can use one of the higher-performance ID strategies outlined in the following sections.
71
-
72
-
The preceding approaches are likely to create [hotspots](#hotspots) for both reads and writes in CockroachDB. {% include {{page.version.version}}/performance/use-hash-sharded-indexes.md %}
67
+
The best practices for generating unique IDs in a distributed database like CockroachDB are very different than for a legacy single-node database.
73
68
74
69
To create unique and non-sequential IDs, we recommend the following approaches (listed in order from best to worst performance):
75
70
@@ -79,6 +74,8 @@ To create unique and non-sequential IDs, we recommend the following approaches (
79
74
| 2. [Use functions to generate unique IDs](#use-functions-to-generate-unique-ids)| Good performance; spreads load well; easy choice | May leave some performance on the table; requires other columns to be useful in queries |
80
75
| 3. [Use `INSERT` with the `RETURNING` clause](#use-insert-with-the-returning-clause-to-generate-unique-ids)| Easy to query against; familiar design | Slower performance than the other options; higher chance of [transaction contention](#transaction-contention)|
81
76
77
+
Traditional approaches using monotonically increasing [`INT`]({% link {{ page.version.version }}/int.md %}) or [`SERIAL`]({% link {{ page.version.version }}/serial.md %}) data types will create [hotspots](#hotspots) for both reads and writes in a distributed database like CockroachDB. {% include {{page.version.version}}/performance/use-hash-sharded-indexes.md %}
78
+
82
79
### Use multi-column primary keys
83
80
84
81
A well-designed multi-column primary key can yield even better performance than a [UUID primary key](#use-functions-to-generate-unique-ids), but it requires more up-front schema design work. To get the best performance, ensure that any monotonically increasing field is located **after** the first column of the primary key. When done right, such a composite primary key should result in:
Note that the above query also follows the [indexing best practice]({% link {{ page.version.version }}/indexes.md %}#best-practices) of indexing all columns in the `WHERE` clause.
157
154
158
-
### Use functions to generate unique IDs
155
+
### Use functions to automatically generate unique IDs
159
156
160
157
{% include {{ page.version.version }}/faq/auto-generate-unique-ids.md %}
Copy file name to clipboardExpand all lines: src/current/v25.3/row-level-security.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -404,7 +404,7 @@ GRANT SELECT, INSERT, UPDATE, DELETE ON invoices TO app_dev;
404
404
405
405
Each application will need to set the tenant context for the session. In this example, you will use the `application_name` session variable to pass in a tenant ID that will later be extracted from the variable.
406
406
407
-
Specifically, the UUID following the period in `application_name` is the tenant ID. We will use the `current_setting()` function in our RLS policies to extract the ID.
407
+
Specifically, the [UUID]({% link {{ page.version.version }}/uuid.md %}) following the period in `application_name` is the tenant ID. We will use the `current_setting()` function in our RLS policies to extract the ID.
408
408
409
409
{{site.data.alerts.callout_danger}}
410
410
For multi-tenancy to work correctly, this setting **must** be reliably managed by the application layer and passed in the connection string.
Copy file name to clipboardExpand all lines: src/current/v25.3/schema-design-table.md
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -288,9 +288,9 @@ For detailed reference documentation for each supported constraint, see [the con
288
288
289
289
To set default values on columns, use the `DEFAULT` constraint. Default values enable you to write queries without the need to specify values for every column.
290
290
291
-
When combined with [supported SQL functions]({% link {{ page.version.version }}/functions-and-operators.md %}), default values can save resources in your application's persistence layer by offloading computation onto CockroachDB. For example, rather than using an application library to generate unique `UUID` values, you can set a default value to be an automatically-generated `UUID` value with the `gen_random_uuid()` SQL function. Similarly, you could use a default value to populate a `TIMESTAMP` column with the current time of day, using the `now()` function.
291
+
When combined with [supported SQL functions]({% link {{ page.version.version }}/functions-and-operators.md %}), default values can save resources in your application's persistence layer by offloading computation onto CockroachDB. For example, rather than using an application library to generate unique [`UUID`]({% link {{ page.version.version }}/uuid.md %}) values, you can set a default value to be an automatically-generated `UUID` value with the `gen_random_uuid()` SQL function. Similarly, you could use a default value to populate a `TIMESTAMP` column with the current time of day, using the `now()` function.
292
292
293
-
For example, in the `vehicles` table definition in `max_init.sql`, you added a `DEFAULT gen_random_uuid()` clause to the `id` column definition. This set the default value to a generated `UUID` value. Now, add a default value to the `creation_time` column:
293
+
For example, in the `vehicles` table definition in `max_init.sql`, you added a `DEFAULT gen_random_uuid()` clause to the `id` column definition. This set the default value to a generated [`UUID`]({% link {{ page.version.version }}/uuid.md %}) value. Now, add a default value to the `creation_time` column:
0 commit comments