什么是 UUID?
UUID(Universally Unique Identifier)是一个 128 位的全局唯一标识符,标准格式为 32 个十六进制字符,分为 5 组,形如 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx。UUID 的设计目标是让分布式系统在不依赖中央协调的情况下生成唯一 ID。
UUID 版本对比
| 版本 | 生成方式 | 可排序 | 碰撞概率 | 主要用途 |
|---|---|---|---|---|
| v1 | 时间戳 + MAC 地址 | 按时间 | 极低 | 遗留系统 |
| v4 | 完全随机(122 bit) | 不可排序 | 极低 | 最通用 |
| v7 (RFC 9562) | 时间戳 + 随机数 | 可排序 | 极低 | 推荐方案 |
UUID v4 详解
UUID v4 是目前最常用的版本,其 122 bit 随机数空间共有 2¹²² 种可能,碰撞概率极低:
- 生成 1 万亿个 ID 后,碰撞概率仅约 10⁻¹⁸
- 每秒生成 10 亿个 ID,需要 100 亿年才可能发生碰撞
UUID v4 的局限性
- 不可排序:完全随机,不适合作为数据库主键
- 索引性能:在 MySQL InnoDB 中,随机插入会导致 B+ 树页分裂和索引碎片
- 存储空间:128 bit 存储,36 字符字符串,比自增 ID 大
什么是 ULID?
ULID(Universally Unique Lexicographically Sortable Identifier)是一种可排序的全局唯一标识符,专为解决 UUID v4 的排序问题而设计。
ULID 的特点
- 128 bit 长度:26 字符 Crockford Base32 编码
- 可排序:按时间戳字典序排序
- 时间精度:毫秒级
- 不区分大小写:Base32 编码无特殊字符
- 无特殊字符:URL 安全
ULID 结构
01AN4Z07BY 79KA1307SR9X4MV3
│ │
│ └── 随机数部分(80 bit)
│
└── 时间戳部分(48 bit,毫秒级 Unix 时间戳)
UUID v7(RFC 9562)
2024 年 5 月正式标准化,是 UUID v4 的最佳替代方案:
- 前 48 bit 为 Unix 毫秒时间戳
- 后 74 bit 为随机数
- 按时间排序,适合数据库索引
- 无需额外协调,可分布式生成
数据库主键选择建议
| 场景 | 推荐方案 |
|---|---|
| 新项目,需要排序 | UUID v7 或 ULID |
| 兼容旧系统 | UUID v4 |
| 内部系统,无分布式需求 | 自增 ID |
| 公开 API | ULID 或 UUID v7 |
安全注意事项
- UUID v4 的随机数应使用密码学安全的随机数生成器(CSPRNG)
- 避免使用
Math.random()生成 UUID - UUID 不应用于安全令牌(如会话 ID),建议使用专门的安全令牌生成器
推荐生成库
| 语言 | UUID | ULID |
|---|---|---|
| JavaScript | uuid | ulid |
| Python | uuid | python-ulid |
| Java | java.util.UUID | ulid-creator |
| Go | google/uuid | oklog/ulid |