UUID v4 和 v7 该怎么选
v4 完全随机,v7 把时间戳放在前面。这个差别看着小,却直接决定了数据库索引的写入性能。本文说明各自适用的场景与选型原则。
选 UUID 时常见的困惑是:都是 128 位,v4 和 v7 有什么区别,该用哪个。
v4:纯随机
v4 的 122 位全部随机:
9f1c3b7e-4a52-4d18-9c66-2b8e5a7d0f31
优点是不可预测、不需要协调、实现最简单。缺点是随机分布导致索引写入变慢——这点常被忽略。
原因在于 B+ 树索引按顺序存储。随机主键意味着每次插入都落在树的随机位置,会频繁触发页分裂、产生大量碎片,缓存命中率也低。数据量大、写入频繁时差距很明显。
v7:时间戳在前,随机在后
v7 的前 48 位是毫秒级 Unix 时间戳,其余是随机位:
0192f3a1-8b40-7c12-9e33-5d7f2a91c004
于是新生成的 ID 天然有序:同一时刻附近写入的记录在索引里也相邻,页分裂大幅减少。对 MySQL / PostgreSQL 这类聚簇或 B+ 树索引,写入性能明显更好。
代价是时间戳可被推断——拿到 ID 能大致知道生成时间。多数业务场景无所谓,但如果 ID 会暴露给外部且时间信息敏感,就要评估一下。
怎么选
- 数据库主键 / 需要有序:v7(或 ULID、雪花 ID 这类同样带时间的方案)
- 需要不可预测(如对外 token、邀请码):v4
- 只是要个唯一标识、写入量不大:v4 也够用,简单就好
- 已有系统用 v4 且写入稳定:不必为了 v7 迁移,收益有限、迁移成本不低
一个折中做法:数据库主键用 v7,对外暴露用 v4 或短 ID,把有序性和安全性分开。
生成时的小细节
- 格式:标准写法是 8-4-4-4-12 并带连字符;存数据库时去掉连字符可省 4 字节,但可读性下降
- 大小写:十六进制不区分大小写,团队统一即可(推荐小写)
- 批量生成:需要造测试数据时用 UUID 生成工具,支持批量与格式配置
别忘了 UUID 是 128 位,比自增 BIGINT 占空间。索引体积更大,一次查询能装入内存的索引项更少——这也是不少团队在超大规模表上仍偏好雪花 ID 的原因。