UUID v4 和 ULID 有什么区别
一句话结论
纯随机 ID 用 UUID v4,需要按时间排序的 ID 用 ULID。ULID 前 48 bit 是毫秒时间戳,因此字典序即时间序,做数据库主键时索引更友好;UUID v4 全随机,插入 B+ 树索引会产生大量随机 IO。两者都是 128 bit,ULID 的字符串形式更短(26 字符 vs 36 字符)。
核心区别对照
| 长度(字符串) | UUID v4 | ULID |
|---|---|---|
| 位结构 | 122 bit 随机 + 版本号 | 48 bit 时间戳 + 80 bit 随机 |
| 能否按时间排序 | 不能,完全无序 | 能,字典序等于时间序 |
| 数据库索引友好度 | 差,随机写入导致页分裂 | 好,近似递增写入 |
| 是否泄露时间 | 不泄露 | 会暴露创建毫秒时间 |
| 大小写 | 通常小写 | Crockford Base32,大写、无易混字符 |
| 标准化 | RFC 9562 国际标准 | 社区规范,非 IETF 标准 |
UUID v4
由 RFC 9562 定义,122 bit 纯随机数,碰撞概率低到实际可忽略(要生成约 2.7×10^18 个才有 1% 碰撞可能)。所有语言、数据库、框架都原生支持,兼容性最好。缺点是完全无序——用作数据库主键时,随机插入会让 B+ 树频繁页分裂,写放大明显。
ULID
ULID 把 48 bit 毫秒时间戳放在高位,因此字符串按字典序排列就等于按创建时间排列,数据库索引可以近似顺序写入,插入性能显著更好。它用 Crockford Base32 编码,26 个字符且去掉了 I/L/O/U 等易混淆字符。代价是会暴露创建时间,且不是正式国际标准,需要引库。
怎么选
- 需要广泛兼容、对接第三方系统 → UUID v4
- 用作数据库主键、关心写入性能 → ULID
- 不能暴露记录创建时间 → UUID v4
相关工具
常见问题
UUID v4 会重复吗
概率上讲几乎不会。需要约 2.7×10^18 个 UUID 才有百万分之一的碰撞概率,一般系统可以放心当作唯一。
能直接用 UUID 当数据库主键吗
能,但要注意它是随机的,高频插入会让索引页分裂、写性能下降。数据量大时优先考虑 ULID 或 UUID v7。
ULID 暴露创建时间有风险吗
有轻微风险:竞争对手或攻击者可以从 ID 推断出记录生成的时间与大致业务量。介意的话用 UUID v4。