关于 UUID 在线生成
UUID 生成器可以生成版本 1、版本 4 或版本 7 的标识符,一次最多一千个,每行一个。版本选择就是这里的全部决策:它决定了标识符编码了什么、如何排序,以及会透露什么。
三个版本都是 128 位的值,都按 8-4-4-4-12 的形式打印成 36 个字符,区别只在于这些位怎么填。版本 4 是 122 个随机位。版本 1 塞进了以 100 纳秒计数的 60 位时间戳、时钟序列和节点标识。版本 7 由 2024 年的 RFC 9562 标准化,以 48 位 Unix 毫秒时间戳开头,因此字典序与生成顺序一致。
如何使用这个开发者工具
- 选版本:要进数据库当键就选 7,标识符必须什么都不透露就选 4,只有当你无法改动的系统要求时才选 1。
- 设置数量,1 到 1000。
- 生成。结果每行一个,可直接用于夹具文件、种子脚本或表格的一列。
- 抽查一个值的第 13 个十六进制位,确认生成的确实是你想要的版本。
- 把版本选择写在表结构的列定义旁边。某个消费方一旦默认了 v7 的有序性,等到有人插入一个 v4,它会静默地出错。
实例:同一毫秒内生成的三个版本 7 值
一次点击生成三个。三者都产生在同一毫秒内,因此高位时间戳完全相同——而作为普通字符串,它们依然按生成顺序排列。
版本 v7
数量 301a0c2c8-1e60-72be-b631-62ee8a95c283
01a0c2c8-1e60-72be-b631-677245e7e821
01a0c2c8-1e60-72be-b631-6b4e18f0a5f8开头 12 个十六进制位就是时间戳:0x01a0c2c81e60 等于 1789974290016,即 2026-09-21T07:04:50.016Z。第 13 位是 7,第 17 位是 b。对比同一次会话里的版本 4——d5bd8caa-62c8-4afd-a4da-ebef1311b3bd——它既没有顺序,也无从解码。
各 UUID 版本编码了什么、如何排序
本工具生成版本 1、4、7。其余版本列在这里,是因为认真做选型时它们总会被提到。
| 版本 | 各位承载的内容 | 是否时间有序 | 会透露什么 |
|---|---|---|---|
| v1 | 60 位时间戳、14 位时钟序列、48 位节点 | 否——时间戳低位排在最前 | 生成时间;在能读到网卡的实现中还有 MAC 地址 |
| v4 | 122 个随机位 | 否 | 什么都不透露 |
| v7 | 48 位 Unix 毫秒时间戳,其后为随机位 | 是,字符串序与字节序都成立 | 生成时间,精确到毫秒 |
| v3 / v5 | 命名空间加名称的 MD5 / SHA-1 | 否 | 名称——对能猜到并重算的人而言 |
| v6 | 把 v1 的时间戳重排为高位在前 | 是 | 与 v1 相同;本工具未提供 |
| v8 | 完全由实现自定义 | 取决于实现 | 取决于实现放了什么进去 |
常见问题排查
使用 v4 作主键后,插入变慢,主键索引膨胀得比预期快。
成因 随机键会写进 B 树的随机页,每次插入命中不同的叶子页。热工作集从「索引的尾部」变成了「整个索引」,而页分裂又留下大量空闲空间。
解决办法 新行改用 v7,它的值单调递增,插入集中落在最右侧的叶子页上。这种索引局部性正是 v7 存在的主要现实理由。
对外 API 通过标识符泄露了记录的创建时间。
成因 这正是 v7 的设计行为:开头 12 个十六进制位就是 Unix 纪元以来的毫秒数,相邻的标识符还会暴露你每秒大致创建多少条记录。
解决办法 把 v7 留作内部主键,对外另发一个不透明标识——只要创建时间或业务量属于敏感信息就这么做。
安全评审指出 v1 标识符暴露了 MAC 地址。
成因 经典的 v1 实现会读取网卡并把地址嵌进去,于是每个标识符都能追溯到一台具体机器。针对服务端生成器,这是一条成立的问题。
解决办法 这里生成的值无需处理,其节点字段是带组播位的随机值。需要排查的是服务端的 v1 生成器,面向用户的场景应改用 v7 或 v4。
批量导入时报主键重复。
成因 几乎可以肯定不是 v4 碰撞:122 个随机位意味着要接近 10 的 18 次方量级的标识符,才有一半概率出现哪怕一次碰撞。
解决办法 去查导入是否跑了两遍、upsert 是否漏了冲突子句,或夹具是否被重复加载。带花括号或大写的 GUID 与小写无括号形式比较时也并不相等。
适合用这个工具的场景
- 创建客户端在访问数据库之前就能自行生成的主键。
- 为夹具或种子文件批量填入一组真实且互不相同的标识符。
- 生成跨服务无需协调即可保持唯一的关联 ID 或链路追踪 ID。
- 把有序标识和不透明标识各生成一批并排比较,做出明确的选型判断。
应该换用别的工具的场景
- 需要简短的对外标识符。36 个字符对 URL 来说太长;可以用进制与编码转换工具把同样的位换成更密的字母表。
- 作为密钥或权限令牌。v4 确实带有 122 个随机位,但 v1 和 v7 可从时间推测,而且 UUID 本来就会被大量写进日志和 URL。请改用安全密码生成器。
- 需要人来口述或手敲的标识符。没人能把一个 UUID 准确抄对;这类场景请用带校验位的短码。
隐私与数据处理
所有值都在当前标签页内生成,不发送也不保存;版本 4 和版本 7 的随机性来自浏览器的密码学安全随机源。有一点值得明确交代:浏览器读不到网卡硬件地址,所以这里的版本 1 用带组播位的随机 48 位值填充节点字段,这正是 RFC 9562 规定的回退做法。它的时间戳则是真实的,会暴露生成时刻,但不暴露地点。
相关开发者工具
常见问题
默认该选哪个版本?
存库记录选版本 7,因为索引局部性是白拿的,顺序也常常有用。标识符要对外暴露、且不能透露时间和业务量时选版本 4。
版本 7 真的已经是标准了吗?
是的。2024 年 5 月发布的 RFC 9562 取代了 RFC 4122,正式定义了版本 6、7、8。此后主流数据库和客户端库陆续加入了原生的版本 7 生成函数。
UUID 能保证唯一吗?
不能。它把碰撞概率压到你可以当作不会发生来做规划的程度,但这是概率论证。数据库上的唯一约束请照留:它能抓住重复的真正成因——重放的导入和被复制的夹具。
UUID 该存成文本还是字节?
数据库有原生 uuid 类型就用原生类型,否则存成 16 字节二进制。文本形式占用两倍空间,其连字符和字母大小写还是跨系统比较出错的固定来源。
多台机器上版本 7 的排序还成立吗?
只在时钟一致的程度上成立。单个生成器内部单调;跨服务器存在几毫秒偏移时全局顺序只是近似的——对索引局部性足够,但替代不了序列号。
为什么我生成的版本 7 看起来几乎一模一样?
同一毫秒内产生的值按设计会共享开头 12 个十六进制位,因为那几位就是时间戳。这段共享前缀正是让它们索引开销低的性质。