From 22000225022db7d3020d66266d8f91ee8ea78024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 18:52:34 +0100 Subject: [PATCH 1/8] Add new UUID functions --- .../miscellaneous-functions.md | 120 +++++++++++++++++- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/functions-and-operators/miscellaneous-functions.md b/functions-and-operators/miscellaneous-functions.md index 57e46f65d6f09..e2f3ba201d1bd 100644 --- a/functions-and-operators/miscellaneous-functions.md +++ b/functions-and-operators/miscellaneous-functions.md @@ -20,15 +20,19 @@ TiDB supports most of the [miscellaneous functions](https://dev.mysql.com/doc/re | [`INET_NTOA()`](#inet_ntoa) | Return the IP address from a numeric value | | [`INET6_ATON()`](#inet6_aton) | Return the numeric value of an IPv6 address | | [`INET6_NTOA()`](#inet6_ntoa) | Return the IPv6 address from a numeric value | -| [`IS_IPV4()`](#is_ipv4) | Whether argument is an IPv4 address | | [`IS_IPV4_COMPAT()`](#is_ipv4_compat) | Whether argument is an IPv4-compatible address | | [`IS_IPV4_MAPPED()`](#is_ipv4_mapped) | Whether argument is an IPv4-mapped address | +| [`IS_IPV4()`](#is_ipv4) | Whether argument is an IPv4 address | | [`IS_IPV6()`](#is_ipv6) | Whether argument is an IPv6 address | | [`IS_UUID()`](#is_uuid) | Whether argument is an UUID | | [`NAME_CONST()`](#name_const) | Can be used to rename a column name | | [`SLEEP()`](#sleep) | Sleep for a number of seconds. Note that for [{{{ .starter }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#starter) and [{{{ .essential }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#essential) clusters, the `SLEEP()` function has a limitation wherein it can only support a maximum sleep time of 300 seconds. | -| [`UUID()`](#uuid) | Return a Universal Unique Identifier (UUID) | +| [`UUID_TIMESTAMP()`](#uuid_timestamp) | Return the timestamp of a UUID | | [`UUID_TO_BIN()`](#uuid_to_bin) | Convert UUID from text format to binary format | +| [`UUID_V4()`](#uuid_v4) | Return a v4 Universal Unique Identifier (UUID) | +| [`UUID_V7()`](#uuid_v7) | Return a v7 Universal Unique Identifier (UUID) | +| [`UUID_VERSION()`](#uuid_version) | Return the UUID version of a UUID | +| [`UUID()`](#uuid) | Return a v1 Universal Unique Identifier (UUID) | | [`VALUES()`](#values) | Defines the values to be used during an INSERT | ### ANY_VALUE() @@ -361,9 +365,117 @@ SELECT SLEEP(1.5); 1 row in set (1.50 sec) ``` +### UUID_VERSION() + +The `UUID_VERSION()` function returns the UUID version of the UUID as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). + +The following example shows a version 1 UUID. + +```sql +SELECT UUID_VERSION('7d31138f-e0ee-11f0-a2db-86f42566cd2c'); +``` + +``` ++------------------------------------------------------+ +| UUID_VERSION('7d31138f-e0ee-11f0-a2db-86f42566cd2c') | ++------------------------------------------------------+ +| 1 | ++------------------------------------------------------+ +1 row in set (0.001 sec) +``` + +The following example shows a version 7 UUID. + +```sql +SELECT UUID_VERSION('019b516b-8ef7-7d74-81e6-9b860112409a'); +``` + +``` ++------------------------------------------------------+ +| UUID_VERSION('019b516b-8ef7-7d74-81e6-9b860112409a') | ++------------------------------------------------------+ +| 7 | ++------------------------------------------------------+ +1 row in set (0.001 sec) +``` + +### UUID_V4() + +The `UUID_V4()` function returns a universally unique identifier (UUID) version 4 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). + +```sql +SELECT UUID_V4(); +``` + +``` ++--------------------------------------+ +| UUID_V4() | ++--------------------------------------+ +| e76d4b18-7f8d-418d-8f9b-f42b4f1d803b | ++--------------------------------------+ +1 row in set (0.001 sec) +``` + +See also [Best practices for UUID](/best-practices/uuid.md). + +### UUID_V7() + +The `UUID_V4()` function returns a universally unique identifier (UUID) version 7 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). + +```sql +SELECT UUID_V7(); +``` + +``` ++--------------------------------------+ +| UUID_V7() | ++--------------------------------------+ +| 019b5171-c5e4-743a-b192-96fbb28d1d7e | ++--------------------------------------+ +1 row in set (0.001 sec) +``` + +See also [Best practices for UUID](/best-practices/uuid.md). + +### UUID_TIMESTAMP() + +The `UUID_TIMESTAMP()` function extracts the timestamp that is stored in a UUID for the UUID versions that include a timestamp and returns this as a UNIX timestamp. + +Only UUIDv1, UUIDv6 and UUIDv7 do store a timestamp. For other UUID versions this function will return `NULL`. + +The example below extracts the timestamp from a UUID. + +```sql +SELECT UUID_TIMESTAMP('019b5171-c5e4-743a-b192-96fbb28d1d7e'); +``` + +``` ++--------------------------------------------------------+ +| UUID_TIMESTAMP('019b5171-c5e4-743a-b192-96fbb28d1d7e') | ++--------------------------------------------------------+ +| 1766597969.380000 | ++--------------------------------------------------------+ +1 row in set (0.001 sec) +``` + +The resulting UNIX timestamp can be used directly with [`FROM_UNIXTIME()`](/functions-and-operators/date-and-time-functions.md) to get a timestamp. + +```sql +SELECT FROM_UNIXTIME(1766597969.380000); +``` + +``` ++----------------------------------+ +| FROM_UNIXTIME(1766597969.380000) | ++----------------------------------+ +| 2025-12-24 18:39:29.380000 | ++----------------------------------+ +1 row in set (0.001 sec) +``` + ### UUID() -The `UUID()` function returns a universally unique identifier (UUID) version 1 as defined in [RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122). +The `UUID()` function returns a universally unique identifier (UUID) version 1 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). ```sql SELECT UUID(); @@ -417,4 +529,4 @@ TABLE t1; | Name | Description | |:------------|:-----------------------------------------------------------------------------------------------| -| [`UUID_SHORT()`](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-short) | Provides a UUID that is unique given certain assumptions not present in TiDB [TiDB #4620](https://github.com/pingcap/tidb/issues/4620) | \ No newline at end of file +| [`UUID_SHORT()`](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-short) | Provides a UUID that is unique given certain assumptions not present in TiDB [TiDB #4620](https://github.com/pingcap/tidb/issues/4620) | From 290fa8c5b25923cba8e1c5b982c172038c994037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 18:57:57 +0100 Subject: [PATCH 2/8] Update functions-and-operators/miscellaneous-functions.md Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- functions-and-operators/miscellaneous-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-and-operators/miscellaneous-functions.md b/functions-and-operators/miscellaneous-functions.md index e2f3ba201d1bd..4697f157a4f16 100644 --- a/functions-and-operators/miscellaneous-functions.md +++ b/functions-and-operators/miscellaneous-functions.md @@ -420,7 +420,7 @@ See also [Best practices for UUID](/best-practices/uuid.md). ### UUID_V7() -The `UUID_V4()` function returns a universally unique identifier (UUID) version 7 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). +The `UUID_V7()` function returns a universally unique identifier (UUID) version 7 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). ```sql SELECT UUID_V7(); From a3fb9ec61869be3a513ff19dc3ca83bff031f9b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 19:00:25 +0100 Subject: [PATCH 3/8] Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- functions-and-operators/miscellaneous-functions.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/functions-and-operators/miscellaneous-functions.md b/functions-and-operators/miscellaneous-functions.md index 4697f157a4f16..2a05dc5eb2bfc 100644 --- a/functions-and-operators/miscellaneous-functions.md +++ b/functions-and-operators/miscellaneous-functions.md @@ -20,9 +20,9 @@ TiDB supports most of the [miscellaneous functions](https://dev.mysql.com/doc/re | [`INET_NTOA()`](#inet_ntoa) | Return the IP address from a numeric value | | [`INET6_ATON()`](#inet6_aton) | Return the numeric value of an IPv6 address | | [`INET6_NTOA()`](#inet6_ntoa) | Return the IPv6 address from a numeric value | +| [`IS_IPV4()`](#is_ipv4) | Whether argument is an IPv4 address | | [`IS_IPV4_COMPAT()`](#is_ipv4_compat) | Whether argument is an IPv4-compatible address | | [`IS_IPV4_MAPPED()`](#is_ipv4_mapped) | Whether argument is an IPv4-mapped address | -| [`IS_IPV4()`](#is_ipv4) | Whether argument is an IPv4 address | | [`IS_IPV6()`](#is_ipv6) | Whether argument is an IPv6 address | | [`IS_UUID()`](#is_uuid) | Whether argument is an UUID | | [`NAME_CONST()`](#name_const) | Can be used to rename a column name | @@ -367,9 +367,9 @@ SELECT SLEEP(1.5); ### UUID_VERSION() -The `UUID_VERSION()` function returns the UUID version of the UUID as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). +The `UUID_VERSION()` function returns the version of a UUID argument as an integer, as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). -The following example shows a version 1 UUID. +The following example gets the version number from a version 1 UUID. ```sql SELECT UUID_VERSION('7d31138f-e0ee-11f0-a2db-86f42566cd2c'); @@ -384,7 +384,7 @@ SELECT UUID_VERSION('7d31138f-e0ee-11f0-a2db-86f42566cd2c'); 1 row in set (0.001 sec) ``` -The following example shows a version 7 UUID. +The following example gets the version number from a version 7 UUID. ```sql SELECT UUID_VERSION('019b516b-8ef7-7d74-81e6-9b860112409a'); @@ -439,9 +439,9 @@ See also [Best practices for UUID](/best-practices/uuid.md). ### UUID_TIMESTAMP() -The `UUID_TIMESTAMP()` function extracts the timestamp that is stored in a UUID for the UUID versions that include a timestamp and returns this as a UNIX timestamp. +The `UUID_TIMESTAMP()` function extracts the timestamp from a time-based UUID and returns it as a UNIX timestamp. -Only UUIDv1, UUIDv6 and UUIDv7 do store a timestamp. For other UUID versions this function will return `NULL`. +UUIDv1, UUIDv6, and UUIDv7 store a timestamp. For other UUID versions, this function returns `NULL`. The example below extracts the timestamp from a UUID. From 018ca9a606d0d3cf064031d840b94d4f2eb445f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 19:01:24 +0100 Subject: [PATCH 4/8] Fix order --- functions-and-operators/miscellaneous-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions-and-operators/miscellaneous-functions.md b/functions-and-operators/miscellaneous-functions.md index 2a05dc5eb2bfc..741288eb21d34 100644 --- a/functions-and-operators/miscellaneous-functions.md +++ b/functions-and-operators/miscellaneous-functions.md @@ -27,12 +27,12 @@ TiDB supports most of the [miscellaneous functions](https://dev.mysql.com/doc/re | [`IS_UUID()`](#is_uuid) | Whether argument is an UUID | | [`NAME_CONST()`](#name_const) | Can be used to rename a column name | | [`SLEEP()`](#sleep) | Sleep for a number of seconds. Note that for [{{{ .starter }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#starter) and [{{{ .essential }}}](https://docs.pingcap.com/tidbcloud/select-cluster-tier#essential) clusters, the `SLEEP()` function has a limitation wherein it can only support a maximum sleep time of 300 seconds. | +| [`UUID()`](#uuid) | Return a v1 Universal Unique Identifier (UUID) | | [`UUID_TIMESTAMP()`](#uuid_timestamp) | Return the timestamp of a UUID | | [`UUID_TO_BIN()`](#uuid_to_bin) | Convert UUID from text format to binary format | | [`UUID_V4()`](#uuid_v4) | Return a v4 Universal Unique Identifier (UUID) | | [`UUID_V7()`](#uuid_v7) | Return a v7 Universal Unique Identifier (UUID) | | [`UUID_VERSION()`](#uuid_version) | Return the UUID version of a UUID | -| [`UUID()`](#uuid) | Return a v1 Universal Unique Identifier (UUID) | | [`VALUES()`](#values) | Defines the values to be used during an INSERT | ### ANY_VALUE() From 582bbacc706528af2c8edc17f41236d4b741d24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 19:34:25 +0100 Subject: [PATCH 5/8] Various updates --- best-practices/uuid.md | 22 +++++++++++++++++++ .../miscellaneous-functions.md | 6 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/best-practices/uuid.md b/best-practices/uuid.md index 36d77654a6392..37649bd20fbe1 100644 --- a/best-practices/uuid.md +++ b/best-practices/uuid.md @@ -19,6 +19,26 @@ When used as a primary key, a UUID offers the following advantages compared with This section describes best practices for storing and indexing UUIDs in TiDB. +### UUID versions + +[RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562) defines 8 different versions of UUID's. TiDB can store any version of UUID and can create v1, v4 and v7 UUID's. + +UUIDv1 is created with the [`UUID()`](/functions-and-operators/miscellaneous-functions.md#uuid) function. + +UUIDv2 is not commonly used. + +UUIDv3 uses a namespace with a MD5 hash. + +UUIDv4 is creatad with the [`UUID_V4()`](/functions-and-operators/miscellaneous-functions.md#uuid_v4) function. This function does not store a timestamp and is fully random except for the bits that store the version and variant. + +UUIDv5 uses a namespace with a SHA1 hash. + +UUIDv6 is modern aternative to UUIDv1 that is field compatible with UUIDv1. + +UUIDv7 is created with the [`UUID_V7()`](/functions-and-operators/miscellaneous-functions.md#uuid_v7) functions. This function is meant as a modern alternative to the version 1 UUID for applications that don't require a UUID that is field compatible. + +UUIDv8 is a custom format UUID that only requires the version bits to be set to 0b1000 (binary representation of 8). + ### Store as binary The textual UUID format looks like this: `ab06f63e-8fe7-11ec-a514-5405db7aad56`, which is a string of 36 characters. By using [`UUID_TO_BIN()`](/functions-and-operators/miscellaneous-functions.md#uuid_to_bin), the textual format can be converted into a binary format of 16 bytes. This allows you to store the text in a [`BINARY(16)`](/data-type-string.md#binary-type) column. When retrieving the UUID, you can use the [`BIN_TO_UUID()`](/functions-and-operators/miscellaneous-functions.md#bin_to_uuid) function to get back to the textual format. @@ -76,3 +96,5 @@ CREATE TABLE `uuid_demo_2` ( ## MySQL compatibility UUIDs can be used in MySQL as well. The `BIN_TO_UUID()` and `UUID_TO_BIN()` functions were introduced in MySQL 8.0. The `UUID()` function is available in earlier MySQL versions as well. + +The `UUID_V4()`, `UUID_V7()`, `UUID_VERSION()` and `UUID_TIMESTAMP()` functions are TiDB specific extensions. diff --git a/functions-and-operators/miscellaneous-functions.md b/functions-and-operators/miscellaneous-functions.md index 741288eb21d34..955fdbfc44cd9 100644 --- a/functions-and-operators/miscellaneous-functions.md +++ b/functions-and-operators/miscellaneous-functions.md @@ -401,7 +401,7 @@ SELECT UUID_VERSION('019b516b-8ef7-7d74-81e6-9b860112409a'); ### UUID_V4() -The `UUID_V4()` function returns a universally unique identifier (UUID) version 4 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). +The `UUID_V4()` function returns a universally unique identifier (UUID) version 4 as defined in [RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562). A UUIDv4 is based on random values and does not store a timestamp. ```sql SELECT UUID_V4(); @@ -530,3 +530,7 @@ TABLE t1; | Name | Description | |:------------|:-----------------------------------------------------------------------------------------------| | [`UUID_SHORT()`](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-short) | Provides a UUID that is unique given certain assumptions not present in TiDB [TiDB #4620](https://github.com/pingcap/tidb/issues/4620) | + +## MySQL compatibility + +The `UUID_V4()`, `UUID_V7()`, `UUID_VERSION()` and `UUID_TIMESTAMP()` functions are TiDB specific extensions. \ No newline at end of file From 5d32c8509f91e950a5deabd3d525bfc956551595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Wed, 24 Dec 2025 19:47:26 +0100 Subject: [PATCH 6/8] Updates from Gemini review --- best-practices/uuid.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/best-practices/uuid.md b/best-practices/uuid.md index 37649bd20fbe1..b086f4889f7af 100644 --- a/best-practices/uuid.md +++ b/best-practices/uuid.md @@ -21,7 +21,7 @@ This section describes best practices for storing and indexing UUIDs in TiDB. ### UUID versions -[RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562) defines 8 different versions of UUID's. TiDB can store any version of UUID and can create v1, v4 and v7 UUID's. +[RFC 9562](https://datatracker.ietf.org/doc/html/rfc9562) defines 8 different versions of UUIDs. TiDB can store any version of UUID and can create v1, v4 and v7 UUIDs. UUIDv1 is created with the [`UUID()`](/functions-and-operators/miscellaneous-functions.md#uuid) function. @@ -29,13 +29,13 @@ UUIDv2 is not commonly used. UUIDv3 uses a namespace with a MD5 hash. -UUIDv4 is creatad with the [`UUID_V4()`](/functions-and-operators/miscellaneous-functions.md#uuid_v4) function. This function does not store a timestamp and is fully random except for the bits that store the version and variant. +UUIDv4 is created with the [`UUID_V4()`](/functions-and-operators/miscellaneous-functions.md#uuid_v4) function. This function does not store a timestamp and is fully random except for the bits that store the version and variant. UUIDv5 uses a namespace with a SHA1 hash. -UUIDv6 is modern aternative to UUIDv1 that is field compatible with UUIDv1. +UUIDv6 is a modern alternative to UUIDv1 that is field compatible with UUIDv1. -UUIDv7 is created with the [`UUID_V7()`](/functions-and-operators/miscellaneous-functions.md#uuid_v7) functions. This function is meant as a modern alternative to the version 1 UUID for applications that don't require a UUID that is field compatible. +UUIDv7 is created with the [`UUID_V7()`](/functions-and-operators/miscellaneous-functions.md#uuid_v7) function. This function is meant as a modern alternative to UUIDv1 for applications that don't require a UUID that is field compatible with UUIDv1. UUIDv8 is a custom format UUID that only requires the version bits to be set to 0b1000 (binary representation of 8). From 7cc95d99911ba806fec199e0bf6726844f44d393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Thu, 25 Dec 2025 16:21:52 +0100 Subject: [PATCH 7/8] Add info about UUID as expression default --- best-practices/uuid.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/best-practices/uuid.md b/best-practices/uuid.md index b086f4889f7af..f2544740fb2b9 100644 --- a/best-practices/uuid.md +++ b/best-practices/uuid.md @@ -93,6 +93,17 @@ CREATE TABLE `uuid_demo_2` ( ) ``` +### Generated UUID as default + +An expression default can be used to generate a UUID for a primary key. Replace `UUID()` with `UUID_V4()` or `UUID_V7()` to use a UUIDv4 or UUIDv7 instead of a UUIDv1 if needed. + +```sql +CREATE TABLE `uuid_demo_3` ( + `uuid` BINARY(16) DEFAULT (UUID_TO_BIN(UUID())), + PRIMARY KEY (`uuid`) +) +``` + ## MySQL compatibility UUIDs can be used in MySQL as well. The `BIN_TO_UUID()` and `UUID_TO_BIN()` functions were introduced in MySQL 8.0. The `UUID()` function is available in earlier MySQL versions as well. From a38d1dca9d21017076d618419053d284cb84584c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20van=20Eeden?= Date: Thu, 25 Dec 2025 16:29:18 +0100 Subject: [PATCH 8/8] Add info about generated columns --- best-practices/uuid.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/best-practices/uuid.md b/best-practices/uuid.md index f2544740fb2b9..1738a467327d2 100644 --- a/best-practices/uuid.md +++ b/best-practices/uuid.md @@ -104,6 +104,15 @@ CREATE TABLE `uuid_demo_3` ( ) ``` +### Converting from binary to text using a generated column + +```sql +CREATE TABLE `uuid_demo_4` ( + `uuid` BINARY(16) PRIMARY KEY, + `uuid_text` CHAR(36) AS (BIN_TO_UUID(uuid)) +); +``` + ## MySQL compatibility UUIDs can be used in MySQL as well. The `BIN_TO_UUID()` and `UUID_TO_BIN()` functions were introduced in MySQL 8.0. The `UUID()` function is available in earlier MySQL versions as well.