如何使用 UUID 生成器
- 选择版本:v4(随机)或 v7(按时间排序)。
- 设置需要的 UUID 数量,可以是一个,也可以批量生成一整列。
- 可选:切换为大写,或去掉连字符。
- 复制单个值或整个列表。
UUID 由您的浏览器使用其密码学安全的随机数生成器生成。它们不会发送到我们的服务器,也不会存储在服务器上,所以没有其他人知道您生成了哪些标识符。
什么是 UUID?
UUID(Universally Unique Identifier,通用唯一识别码)是一个 128 位的值,可以在任何机器上独立生成,与其他任何 UUID 重复的概率小到可以忽略。它不需要中央注册机构,也不需要往返查询数据库,因此非常适合分布式系统、离线客户端以及合并多个来源的数据。它也常用作请求 ID,以及令牌中的 jti 声明,您可以用 JWT解码器查看这些令牌。GUID(Globally Unique Identifier,全局唯一标识符)是 Microsoft 对同一事物的叫法。
UUID 写成 32 个十六进制数字,分为五组,用连字符隔开,格式为 8-4-4-4-12(共 36 个字符):
f47ac10b-58cc-4372-a567-0e02b2c3d479
^ ^
| 变体(8、9、a 或 b)
版本(4)
第三组的第一位数字是版本;第四组的第一位数字编码了变体。现行规范是 RFC 9562(2024 年),它取代了 RFC 4122,并新增了版本 6、7 和 8。
版本 4 与版本 7 的区别
| UUID v4 | UUID v7 | |
|---|---|---|
| 内容 | 122 个随机位(6 位固定用于版本和变体) | 48 位以毫秒为单位的 Unix 时间戳,后接随机位 |
| 排序 | 随机 | 大致按时间先后 |
| 会暴露 | 无 | 其创建时间 |
| 最适合 | 令牌、公开 ID、一般用途 | 数据库主键、事件日志 |
为什么 v7 更适合数据库索引
主键通常存储在 B 树索引中。随机的 v4 值会落在随机的位置,每次插入都会触及不同的页,导致大表出现页分裂、缓存局部性差和索引膨胀。由于 v7 UUID 以时间戳开头,新值会追加到索引末尾附近,与自增整数很像,同时又保留了全局唯一、可由客户端生成的 ID 的优点。
常见陷阱
- 把 UUID 存成文本。36 个字符的字符串所占空间是 16 个原始字节的两倍多。请使用原生的
uuid类型(PostgreSQL)或BINARY(16)(MySQL)。 - 把 UUID 当作密钥。v4 值很难猜到,但它们是标识符,而不是凭证。v7 值会暴露创建时间,而且部分可预测。密码重置和 API 密钥请使用专门的随机令牌。
- 区分大小写的比较。RFC 9562 规定输出使用小写,但要求输入无论大小写都应被接受。比较字符串之前请先统一大小写。
- 随机源不够强。用
Math.random()生成 v4 UUID 会削弱其唯一性。请使用密码学安全的生成器。
在代码中生成 UUID
// JavaScript(浏览器和 Node.js)
crypto.randomUUID(); // v4
# Python
import uuid
uuid.uuid4()
uuid.uuid7() # Python 3.14+
-- PostgreSQL
SELECT gen_random_uuid(); -- v4 (PostgreSQL 13+)
SELECT uuidv7(); -- PostgreSQL 18+
// Java
java.util.UUID.randomUUID();
// C# / .NET
Guid.NewGuid(); // v4
Guid.CreateVersion7(); // .NET 9+
# Shell(Linux、macOS)
uuidgen
常见问题
两个 UUID 会相同吗?
理论上会,实际上不会。v4 有 122 个随机位,可能的取值多得惊人,要每秒生成数十亿个 UUID 并持续几十年,才有可能出现一个重复。实际系统中的冲突几乎总是来自有缺陷的随机数生成器或被复制的数据,而不是偶然。
UUID 和 GUID 有什么区别?
实际上没有区别。GUID 是 Microsoft 技术中使用的术语;格式和长度都相同。
应该用 v4 还是 v7?
数据库主键以及任何需要按创建时间排序的场景,请用 v7。当 ID 不应透露任何信息时(例如出现在公开 URL 中的标识符),请用 v4。
nil UUID 有效吗?
有效。00000000-0000-0000-0000-000000000000 是特殊的 nil UUID(空 UUID),RFC 9562 还定义了一个全部由 f 组成的 max UUID(最大 UUID)。两者常被用作占位符。
更新于