什么是ULID?
ULID(通用唯一词典排序标识符)是一种128位标识符格式,旨在克服UUID的局限性。它由以下部分组成:
- 时间戳:48位毫秒精度的Unix时间
- 随机性:80位加密安全的随机数据
- 编码:Base32表示(26个字符)
格式示例:01ARZ3NDEKTSV4RRFFQ69G5FAV
ULID工作原理
- 生成48位时间戳(毫秒级Unix时间)
- 生成80位加密安全随机数据
- 将时间戳(最高有效位)与随机性(最低有效位)组合
- 使用Crockford的Base32字母表编码整个128位值
- 结果是一个26字符的字符串(前10个字符是时间戳,后16个是随机性)
优势与考虑因素
优势 | 考虑因素 |
---|---|
|
|
ULID结构
组件 | 位数 | 字符数 | 描述 |
---|---|---|---|
时间戳 | 48位 | 10个字符 | 以Base32编码的Unix时间戳(毫秒) |
随机性 | 80位 | 16个字符 | 以Base32编码的随机字节 |
ULID与UUID比较
特性 | ULID | UUID v1 | UUID v4 | UUID v7 |
---|---|---|---|---|
大小 | 128位 | 128位 | 128位 | 128位 |
字符串长度 | 26个字符 | 36个字符 | 36个字符 | 36个字符 |
基于时间 | ✅ | ✅ | ❌ | ✅ |
自然排序 | ✅ | ❌ | ❌ | ✅ |
URL安全 | ✅ | ❌ | ❌ | ❌ |
MAC地址暴露 | ❌ | ✅ | ❌ | ❌ |
随机组件 | ✅ | ❌ | ✅ | ✅ |
规范标准 | ❌ | ✅ | ✅ | ⚠️ 草案 |
常见使用场景
- 数据库主键:性能优化的索引
- 分布式系统:无需协调的生成
- API:干净、URL安全的标识符
- 时间序列数据:原生时间顺序排序
- 日志系统:可排序的事件标识符
- 现代应用程序:UUID限制成为问题的场景
为什么选择ULID?
- 可排序性:按创建时间进行词典排序
- URL安全性:不需要URL编码(与带有连字符的UUID不同)
- 紧凑性:26个字符vs UUID的36个
- 不区分大小写:减少用户输入错误
- 单调性:同一毫秒内可选的单调排序
- 无特殊字符:简单的纯字母数字格式
常见问题
ULID如何与UUID v7比较?
两者都使用Unix时间戳实现可排序性并包含随机组件。主要区别在于编码(Base32 vs 十六进制)、格式(26个字符 vs 36个)和标准化(UUID v7正处于RFC规范草案阶段)。
能否从ULID中提取创建时间?
是的。前10个字符代表毫秒精度的Unix时间戳,可以解码并转换为标准日期时间格式。
ULID是否兼容UUID数据库字段?
不兼容。ULID使用不同的格式,需要存储为字符串或二进制数据,而不是原生UUID数据库类型。
ULID中的单调性是什么?
一些ULID实现提供单调选项,通过增加在同一时间戳创建的ULID的随机组件,确保即使在同一毫秒内也能保持顺序排序。
ULID使用什么字符集?
ULID使用Crockford的Base32编码(0-9,A-Z不包括I、L、O、U),这种设计旨在减少ID在手动读取或输入时的混淆和转录错误。
资源
Crockford的Base32字母表
编码值 | 字符 | 备注 |
---|---|---|
0-9 | 0-9 | 十进制数字 |
10-31 | A-Z | 不包括I、L、O、U以提高可读性 |
字符:0123456789ABCDEFGHJKMNPQRSTVWXYZ
此编码在解码时不区分大小写(但ULID通常以大写形式生成)。