← 返回文章列表

UUID 该用哪个版本?v1、v4、v7 与不该用 UUID 的场景

标识符避坑

三个常用版本对比

版本组成特点适用
v1时间戳 + 节点(MAC)大致有序,但泄漏时间与设备信息内部、需顺序追踪的历史系统
v4122 位随机最常用,无顺序通用唯一标识
v7时间戳前缀 + 随机可按时间排序,索引友好数据库主键、日志 ID

碰撞概率有多大

v4 需要生成大约 2.7×10¹⁸ 个UUID 才有 50% 概率出现一次碰撞。真实业务规模下“重复”几乎不是问题,真正的痛点是无序。

做主键的性能陷阱

随机 UUID 会让 B+ 树索引随机插入,带来页分裂与写放大;数据量增长后,插入性能和缓存命中率都会下降。解决办法是让 ID 保持时间局部性:用 v7 / ULID,或用数据库自增、雪花 ID。已有大量 v4 主键的系统,也可以保留 UUID 作对外标识、内部另设顺序主键。

三个不该用 UUID 的场景

  1. 需要短、能口头传播的标识:邀请码、短链用 UUID 太长,换成更短的编码(如 Base62 随机串);
  2. 需要人工识别与排错:订单号这类用有语义的规则更好读;
  3. 当作安全令牌:见下。

ID 方案怎么选

方案有序性长度适用
数据库自增天然有序小单库、内部系统
雪花 ID时间有序64 位整数分布式、需紧凑 ID
UUID v4无序36 字符通用唯一标识、对外暴露
UUID v7 / ULID时间有序36 / 26 字符数据库主键、日志追踪

生成与使用建议

  1. 用系统或标准库生成(crypto.randomUUID()、各语言 uuid 库),别用 Math.random() 拼,它不是密码学安全的;
  2. 存储用 16 字节二进制或去连字符的 32 字符形式,比 36 字符字符串更省空间、比较更快;
  3. 需要按时间查询就让 ID 自带时间序(v7 / ULID),否则额外加一列创建时间并建索引;
  4. 对外暴露前评估信息泄漏:v1 带时间与 MAC,v7 带创建时间,v4 不带任何结构信息。

几个常被问到的问题

UUID 能当令牌吗?不能。v4 只有 122 位随机,且没有有效期、作用域与撤销语义;令牌应用 256 位随机串结合服务端校验。UUID 会泄漏信息吗?v1 泄漏生成时间与设备 MAC,v7 泄漏创建时间(通常可接受),v4 不泄漏任何结构信息。ULID 和 v7 选哪个?都能按时间排序:ULID 更短(26 字符),v7 是标准 UUID 格式(36 字符),按团队习惯选。

动手试试:UUID 生成