UUIDv7 生成
生成的 UUID 包含一个 Unix 毫秒时间戳(48 位),后跟版本“7”(4 位)、计数器(42 位)以区分毫秒内的 UUID(包括变体字段“2”,2 位)和随机字段(32 位)。对于给定的时间戳 (unix_ts_ms),计数器从随机值开始,并且对于每个新的 UUID 递增 1,直到时间戳发生变化。如果计数器溢出,则时间戳字段递增 1,并且计数器重置为新的随机起始值。UUID 生成函数保证在并发运行的线程和查询中,所有函数调用内的时间戳内的计数器字段单调递增。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
| unix_ts_ms |
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
| unix_ts_ms | ver | counter_high_bits |
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
|var| counter_low_bits |
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
| rand_b |
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
Snowflake ID 生成
生成的 Snowflake ID 包含当前 Unix 毫秒时间戳(41 + 1 个最高零位),后跟机器 ID(10 位)和计数器(12 位)以区分毫秒内的 ID。对于给定的时间戳 (unix_ts_ms),计数器从 0 开始,并且对于每个新的 Snowflake ID 递增 1,直到时间戳发生变化。如果计数器溢出,则时间戳字段递增 1,并且计数器重置为 0。
注意
生成的 Snowflake ID 基于 1970-01-01 的 UNIX 纪元。虽然对于 Snowflake ID 的纪元没有标准或建议,但其他系统中的实现可能会使用不同的纪元,例如 Twitter/X (2010-11-04) 或 Mastodon (2015-01-01)。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
|0| timestamp |
├─┼ ┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
| | machine_id | machine_seq_num |
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
UUIDNumToString
引入于:v1.1
接受 UUID 的二进制表示形式,其格式由 variant 可选指定(默认值为 Big-endian),并返回一个包含文本格式的 36 个字符的字符串。
语法
UUIDNumToString(binary[, variant])
参数
返回值
返回 UUID 字符串。 String
示例
使用示例
SELECT
'a/<@];!~p{jTj={)' AS bytes,
UUIDNumToString(toFixedString(bytes, 16)) AS uuid
┌─bytes────────────┬─uuid─────────────────────────────────┐
│ a/<@];!~p{jTj={) │ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │
└──────────────────┴──────────────────────────────────────┘
Microsoft 变体
SELECT
'@</a;]~!p{jTj={)' AS bytes,
UUIDNumToString(toFixedString(bytes, 16), 2) AS uuid
┌─bytes────────────┬─uuid─────────────────────────────────┐
│ @</a;]~!p{jTj={) │ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │
└──────────────────┴──────────────────────────────────────┘
UUIDStringToNum
引入于:v1.1
接受格式为 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 的 36 个字符的字符串,并返回其二进制表示形式的 FixedString(16),其格式由 variant 可选指定(默认值为 Big-endian)。
语法
UUIDStringToNum(string[, variant = 1])
参数
返回值
返回 string 的二进制表示形式。 FixedString(16)
示例
使用示例
SELECT
'612f3c40-5d3b-217e-707b-6a546a3d7b29' AS uuid,
UUIDStringToNum(uuid) AS bytes
┌─uuid─────────────────────────────────┬─bytes────────────┐
│ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │ a/<@];!~p{jTj={) │
└──────────────────────────────────────┴──────────────────┘
Microsoft 变体
SELECT
'612f3c40-5d3b-217e-707b-6a546a3d7b29' AS uuid,
UUIDStringToNum(uuid, 2) AS bytes
┌─uuid─────────────────────────────────┬─bytes────────────┐
│ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │ @</a;]~!p{jTj={) │
└──────────────────────────────────────┴──────────────────┘
UUIDToNum
引入于:v24.5
接受一个 UUID 并将其二进制表示形式作为 FixedString(16) 返回,其格式由 variant 可选指定(默认值为 Big-endian)。此函数取代了对两个单独函数 UUIDStringToNum(toString(uuid)) 的调用,因此无需从 UUID 转换为字符串即可提取 UUID 的字节。
语法
UUIDToNum(uuid[, variant = 1])
参数
返回值
返回 UUID 的二进制表示形式。 FixedString(16)
示例
使用示例
SELECT
toUUID('612f3c40-5d3b-217e-707b-6a546a3d7b29') AS uuid,
UUIDToNum(uuid) AS bytes
┌─uuid─────────────────────────────────┬─bytes────────────┐
│ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │ a/<@];!~p{jTj={) │
└──────────────────────────────────────┴──────────────────┘
Microsoft 变体
SELECT
toUUID('612f3c40-5d3b-217e-707b-6a546a3d7b29') AS uuid,
UUIDToNum(uuid, 2) AS bytes
┌─uuid─────────────────────────────────┬─bytes────────────┐
│ 612f3c40-5d3b-217e-707b-6a546a3d7b29 │ @</a;]~!p{jTj={) │
└──────────────────────────────────────┴──────────────────┘
UUIDv7ToDateTime
引入于:v24.5
返回 UUID 版本 7 的时间戳组件。
语法
UUIDv7ToDateTime(uuid[, timezone])
参数
返回值
返回具有毫秒精度的时间戳。如果 UUID 不是有效的版本 7 UUID,则返回 1970-01-01 00:00:00.000。 DateTime64(3)
示例
使用示例
SELECT UUIDv7ToDateTime(toUUID('018f05c9-4ab8-7b86-b64e-c9f03fbd45d1'))
┌─UUIDv7ToDateTime(toUUID('018f05c9-4ab8-7b86-b64e-c9f03fbd45d1'))─┐
│ 2024-04-22 15:30:29.048 │
└──────────────────────────────────────────────────────────────────┘
带时区
SELECT UUIDv7ToDateTime(toUUID('018f05c9-4ab8-7b86-b64e-c9f03fbd45d1'), 'America/New_York')
┌─UUIDv7ToDateTime(toUUID('018f05c9-4ab8-7b86-b64e-c9f03fbd45d1'), 'America/New_York')─┐
│ 2024-04-22 11:30:29.048 │
└─────────────────────────────────────────────────────────────────────────────────────┘
dateTime64ToSnowflake
引入于:v21.10
将 DateTime64 转换为给定时间点的第一个 Snowflake ID。
语法
dateTime64ToSnowflake(value)
参数
返回值
返回将输入值转换为该时间点的第一个 Snowflake ID。 Int64
示例
使用示例
WITH toDateTime64('2021-08-15 18:57:56.492', 3, 'Asia/Shanghai') AS dt64 SELECT dateTime64ToSnowflake(dt64);
┌─dateTime64ToSnowflake(dt64)─┐
│ 1426860704886947840 │
└─────────────────────────────┘
dateTime64ToSnowflakeID
引入于: v24.6
将 DateTime64 值转换为给定时间点的第一个 Snowflake ID。
语法
dateTime64ToSnowflakeID(value[, epoch])
参数
value — 日期和时间。 DateTime64
epoch — Snowflake ID 的纪元,自 1970-01-01 以来以毫秒为单位。默认值为 0(1970-01-01)。对于 Twitter/X 纪元(2015-01-01),提供 1288834974657。 UInt*
返回值
输入值转换为 UInt64
示例
简单
SELECT dateTime64ToSnowflakeID(toDateTime64('2021-08-15 18:57:56', 3, 'Asia/Shanghai'))
dateTimeToSnowflake
引入于:v21.10
将 DateTime 值转换为给定时间点的第一个 Snowflake ID。
语法
dateTimeToSnowflake(value)
参数
返回值
返回将输入值作为该时间点的第一个 Snowflake ID。 Int64
示例
使用示例
WITH toDateTime('2021-08-15 18:57:56', 'Asia/Shanghai') AS dt SELECT dateTimeToSnowflake(dt);
┌─dateTimeToSnowflake(dt)─┐
│ 1426860702823350272 │
└─────────────────────────┘
dateTimeToSnowflakeID
引入于: v24.6
将 DateTime 值转换为给定时间点的第一个 Snowflake ID。
语法
dateTimeToSnowflakeID(value[, epoch])
参数
value — 日期和时间。 DateTime
epoch — Snowflake ID 的纪元,自 1970-01-01 以来以毫秒为单位。默认值为 0(1970-01-01)。对于 Twitter/X 纪元(2015-01-01),提供 1288834974657。 UInt*
返回值
输入值转换为 UInt64
示例
简单
SELECT dateTimeToSnowflakeID(toDateTime('2021-08-15 18:57:56', 'Asia/Shanghai'))
dateTimeToUUIDv7
引入于: v25.9
将 DateTime 值转换为给定时间的 UUIDv7。
有关 UUID 结构、计数器管理和并发保证的详细信息,请参阅章节 “UUIDv7 生成”。
注意
截至 2025 年 9 月,版本 7 UUID 仍处于草案状态,其布局将来可能会发生变化。
语法
参数
返回值
返回 UUIDv7。 UUID
示例
使用示例
SELECT dateTimeToUUIDv7(toDateTime('2021-08-15 18:57:56', 'Asia/Shanghai'));
┌─dateTimeToUUIDv7(toDateTime('2021-08-15 18:57:56', 'Asia/Shanghai'))─┐
│ 018f05af-f4a8-778f-beee-1bedbc95c93b │
└─────────────────────────────────────────────────────────────────────────┘
相同时间戳的多个 UUID
SELECT dateTimeToUUIDv7(toDateTime('2021-08-15 18:57:56'));
SELECT dateTimeToUUIDv7(toDateTime('2021-08-15 18:57:56'));
┌─dateTimeToUUIDv7(t⋯08-15 18:57:56'))─┐
│ 017b4b2d-7720-76ed-ae44-bbcc23a8c550 │
└──────────────────────────────────────┘
┌─dateTimeToUUIDv7(t⋯08-15 18:57:56'))─┐
│ 017b4b2d-7720-76ed-ae44-bbcf71ed0fd3 │
└──────────────────────────────────────┘
generateSnowflakeID
引入于: v24.6
生成一个 Snowflake ID。
函数 generateSnowflakeID 保证在并发运行的线程和查询中,所有函数调用内的计数器字段单调递增。
有关实现细节,请参阅章节 “Snowflake ID 生成”。
语法
generateSnowflakeID([expr, [machine_id]])
参数
expr — 用于绕过 公共子表达式消除 的任意 表达式,如果函数在查询中多次调用。表达式的值不会影响返回的 Snowflake ID。可选。 - machine_id — 机器 ID,使用最低 10 位。 Int64。可选。
返回值
返回 Snowflake ID。 UInt64
示例
使用示例
CREATE TABLE tab (id UInt64)
ENGINE = MergeTree()
ORDER BY tuple();
INSERT INTO tab SELECT generateSnowflakeID();
SELECT * FROM tab;
┌──────────────────id─┐
│ 7199081390080409600 │
└─────────────────────┘
每行生成的多个 Snowflake ID
SELECT generateSnowflakeID(1), generateSnowflakeID(2);
┌─generateSnowflakeID(1)─┬─generateSnowflakeID(2)─┐
│ 7199081609652224000 │ 7199081609652224001 │
└────────────────────────┴────────────────────────┘
带有表达式和机器 ID
SELECT generateSnowflakeID('expr', 1);
┌─generateSnowflakeID('expr', 1)─┐
│ 7201148511606784002 │
└────────────────────────────────┘
generateUUIDv4
引入于:v1.1
生成一个 版本 4 UUID。
语法
参数
expr — 可选。用于绕过 公共子表达式消除 的任意表达式,如果函数在查询中多次调用。表达式的值不会影响返回的 UUID。
返回值
返回 UUIDv4。 UUID
示例
使用示例
SELECT generateUUIDv4(number) FROM numbers(3);
┌─generateUUIDv4(number)───────────────┐
│ fcf19b77-a610-42c5-b3f5-a13c122f65b6 │
│ 07700d36-cb6b-4189-af1d-0972f23dc3bc │
│ 68838947-1583-48b0-b9b7-cf8268dd343d │
└──────────────────────────────────────┘
公共子表达式消除
SELECT generateUUIDv4(1), generateUUIDv4(1);
┌─generateUUIDv4(1)────────────────────┬─generateUUIDv4(2)────────────────────┐
│ 2d49dc6e-ddce-4cd0-afb8-790956df54c1 │ 2d49dc6e-ddce-4cd0-afb8-790956df54c1 │
└──────────────────────────────────────┴──────────────────────────────────────┘
generateUUIDv7
引入于:v24.5
生成一个 版本 7 UUID。
有关 UUID 结构、计数器管理和并发保证的详细信息,请参阅章节 “UUIDv7 生成”。
注意
截至 2025 年 9 月,版本 7 UUID 仍处于草案状态,其布局将来可能会发生变化。
语法
参数
expr — 可选。用于绕过 公共子表达式消除 的任意表达式,如果函数在查询中多次调用。表达式的值不会影响返回的 UUID。 Any
返回值
返回 UUIDv7。 UUID
示例
使用示例
SELECT generateUUIDv7(number) FROM numbers(3);
┌─generateUUIDv7(number)───────────────┐
│ 019947fb-5766-7ed0-b021-d906f8f7cebb │
│ 019947fb-5766-7ed0-b021-d9072d0d1e07 │
│ 019947fb-5766-7ed0-b021-d908dca2cf63 │
└──────────────────────────────────────┘
公共子表达式消除
SELECT generateUUIDv7(1), generateUUIDv7(1);
┌─generateUUIDv7(1)────────────────────┬─generateUUIDv7(1)────────────────────┐
│ 019947ff-0f87-7d88-ace0-8b5b3a66e0c1 │ 019947ff-0f87-7d88-ace0-8b5b3a66e0c1 │
└──────────────────────────────────────┴──────────────────────────────────────┘
snowflakeIDToDateTime
引入于: v24.6
将 Snowflake ID 的时间戳组件作为 DateTime 类型的值返回。
语法
snowflakeIDToDateTime(value[, epoch[, time_zone]])
参数
value — Snowflake ID。 UInt64
epoch — 可选。Snowflake ID 的纪元,自 1970-01-01 以来以毫秒为单位。默认值为 0(1970-01-01)。对于 Twitter/X 纪元(2015-01-01),提供 1288834974657。 UInt*
time_zone — 可选。 时区。该函数根据时区解析 time_string。 String
返回值
返回 value 的时间戳组件。 DateTime
示例
使用示例
SELECT snowflakeIDToDateTime(7204436857747984384) AS res
┌─────────────────res─┐
│ 2024-06-06 10:59:58 │
└─────────────────────┘
snowflakeIDToDateTime64
引入于: v24.6
将 Snowflake ID 的时间戳组件作为 DateTime64 类型的值返回。
语法
snowflakeIDToDateTime64(value[, epoch[, time_zone]])
参数
value — Snowflake ID。 UInt64
epoch — 可选。Snowflake ID 的纪元,自 1970-01-01 以来以毫秒为单位。默认值为 0(1970-01-01)。对于 Twitter/X 纪元(2015-01-01),提供 1288834974657。 UInt*
time_zone — 可选。 时区。该函数根据时区解析 time_string。 String
返回值
将 value 的时间戳组件作为具有 scale = 3 的 DateTime64 返回,即毫秒级精度。 DateTime64
示例
使用示例
SELECT snowflakeIDToDateTime64(7204436857747984384) AS res
┌─────────────────res─┐
│ 2024-06-06 10:59:58 │
└─────────────────────┘
snowflakeToDateTime
引入于:v21.10
提取 Snowflake ID 在 DateTime 格式中的时间戳组件。
语法
snowflakeToDateTime(value[, time_zone])
参数
value — Snowflake ID。 Int64
time_zone — 可选。 时区。该函数根据时区解析 time_string。 String
返回值
返回 value 的时间戳组件。 DateTime
示例
使用示例
SELECT snowflakeToDateTime(CAST('1426860702823350272', 'Int64'), 'UTC');
┌─snowflakeToDateTime(CAST('1426860702823350272', 'Int64'), 'UTC')─┐
│ 2021-08-15 10:57:56 │
└──────────────────────────────────────────────────────────────────┘
snowflakeToDateTime64
引入于:v21.10
提取 Snowflake ID 在 DateTime64 格式中的时间戳组件。
语法
snowflakeToDateTime64(value[, time_zone])
参数
value — Snowflake ID。 Int64
time_zone — 可选。 时区。该函数根据时区解析 time_string。 String
返回值
返回 value 的时间戳组件。 DateTime64(3)
示例
使用示例
SELECT snowflakeToDateTime64(CAST('1426860802823350272', 'Int64'), 'UTC');
┌─snowflakeToDateTime64(CAST('1426860802823350272', 'Int64'), 'UTC')─┐
│ 2021-08-15 10:58:19.841 │
└────────────────────────────────────────────────────────────────────┘
toUUIDOrDefault
引入于:v21.1
将字符串值转换为 UUID 类型。如果转换失败,则返回默认 UUID 值,而不是抛出错误。
此函数尝试解析标准 UUID 格式(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)的 36 个字符的字符串。如果字符串无法转换为有效的 UUID,则函数返回提供的默认 UUID 值。
语法
toUUIDOrDefault(string, default)
参数
string — 要转换为 UUID 的 36 个字符的字符串或 FixedString(36)。 - default — 如果第一个参数无法转换为 UUID 类型,则返回的 UUID 值。
返回值
如果转换成功,则返回转换后的 UUID,否则返回默认 UUID。 UUID
示例
成功转换返回解析后的 UUID
SELECT toUUIDOrDefault('61f0c404-5cb3-11e7-907b-a6006ad3dba0', toUUID('59f0c404-5cb3-11e7-907b-a6006ad3dba0'));
┌─toUUIDOrDefault('61f0c404-5cb3-11e7-907b-a6006ad3dba0', toUUID('59f0c404-5cb3-11e7-907b-a6006ad3dba0'))─┐
│ 61f0c404-5cb3-11e7-907b-a6006ad3dba0 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
转换失败返回默认 UUID
SELECT toUUIDOrDefault('-----61f0c404-5cb3-11e7-907b-a6006ad3dba0', toUUID('59f0c404-5cb3-11e7-907b-a6006ad3dba0'));
┌─toUUIDOrDefault('-----61f0c404-5cb3-11e7-907b-a6006ad3dba0', toUUID('59f0c404-5cb3-11e7-907b-a6006ad3dba0'))─┐
│ 59f0c404-5cb3-11e7-907b-a6006ad3dba0 │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
toUUIDOrNull
引入于:v20.12
将输入值转换为 UUID 类型的值,但在发生错误时返回 NULL。
类似于 toUUID,但在转换错误时返回 NULL,而不是抛出异常。
支持的参数
- 标准格式(8-4-4-4-12 十六进制数字)的 UUID 字符串表示形式。
- 不带连字符的 UUID 字符串表示形式(32 个十六进制数字)。
不支持的参数(返回 NULL)
- 无效的字符串格式。
- 非字符串类型。
- 格式错误的 UUID。
语法
参数
返回值
如果成功,则返回 UUID 值,否则返回 NULL。 UUID 或 NULL
示例
使用示例
SELECT
toUUIDOrNull('550e8400-e29b-41d4-a716-446655440000') AS valid_uuid,
toUUIDOrNull('invalid-uuid') AS invalid_uuid
┌─valid_uuid───────────────────────────┬─invalid_uuid─┐
│ 550e8400-e29b-41d4-a716-446655440000 │ ᴺᵁᴸᴸ │
└──────────────────────────────────────┴──────────────┘