ULID 生成器
生成可排序的 26 位 ULID(Crockford base32)并可将内嵌时间戳解码回日期,非常适合作为数据库主键。
可排序的唯一标识。 ULID 为 26 位字符:前 10 位以毫秒编码创建时间,后 16 位为随机值。因此它可按字典序排序,也能安全用作主键。在浏览器内生成。
生成可排序的 26 位 ULID(Crockford base32)并可将内嵌时间戳解码回日期,非常适合作为数据库主键。
可排序的唯一标识。 ULID 为 26 位字符:前 10 位以毫秒编码创建时间,后 16 位为随机值。因此它可按字典序排序,也能安全用作主键。在浏览器内生成。
ULID 是一个 128 位标识符,宽度与 UUID 相同,分为两部分:48 位毫秒时间戳,后接 80 位随机数据。它以 26 个字符的 Crockford base32 表示,而不是 UUID 那种带连字符的 36 字符十六进制,因此更短、大小写不敏感,并且剔除了最容易看错的字符——字母表中不含 I、L、O 和 U。
真正关键的差异不在编码,而在排序。由于时间戳占据高位,而 base32 保持字节序,把 ULID 当作普通字符串排序,结果就是按创建时间排序。同一毫秒内生成的两个 ID 会退化为比较随机部分,但跨毫秒的顺序是精确的。
UUIDv4 是均匀随机的,而这恰恰是聚簇索引最不需要的性质。每次插入都落在 B 树的随机位置,数据库因此不断分裂页面并触碰冷页。索引膨胀到超出必要的体积,写入吞吐也随表增长而劣化。这是 MySQL InnoDB 和 SQL Server 中 UUID 主键众所周知的问题。
按时间有序的标识符会追加在索引的右端附近,访问模式与自增整数一致。你既保留了客户端生成全局唯一键的好处——无需往返取 ID、服务之间无需协调、跨分片合并安全——又避开了索引碎片化。
RFC 9562 标准化的 UUIDv7 用标准 UUID 的格式和布局实现了与 ULID 相同的效果。如果你的技术栈已经具备原生 UUID 列类型和配套工具,如今通常应优先选 UUIDv7,理由很简单:它能直接融入既有生态。而当你希望在 URL 或日志中使用更短、更友好的文本形式时,ULID 依然有吸引力。
无论选哪种,都要清楚时间戳对任何持有该 ID 的人都是可见的。创建时间会泄露,相邻 ID 会暴露先后顺序——凡是枚举关系或时间信息敏感的场景都不要使用。另外,每毫秒 80 位随机数意味着碰撞在实践中不必担心,但 ULID 并不是秘密,绝不能当作访问凭证使用。