ULID 生成器
批次生成可作為 UUID 替代方案、按時間順序可排序的 ID「ULID」。
使用小貼士
- ULID 的前 10 個字元是時間戳(生成時刻),其餘 16 個字元為隨機值。除非在同一毫秒內生成,僅按字串排序即可還原生成時刻的先後順序。
- 如果資料庫主鍵使用完全隨機的 UUID v4,新行的插入位置會是隨機的,容易導致 B-tree 索引碎片化;而 ULID 大致按時間順序排列,插入位置相對連續,因此能緩解這一問題。
- ULID 使用 26 個字元的 Crockford Base32 編碼(從 `0`-`9`、`A`-`Z` 中去除容易混淆的 I、L、O、U,共 32 個字元),比 UUID(含連字元共 36 個字元)更短,在不區分大小寫的環境中也能安全使用。
- 如需與 Nano ID、UUID v4 進行格式對比,請參閱姊妹工具「Nano ID 生成」頁面上的對比表。
常見問題
ULID(Universally Unique Lexicographically Sortable Identifier,通用唯一按字典序排序識別符號)是一種與 UUID 類似、可生成全域性唯一 ID 的規範,其特點在於內含生成時刻的資訊,因此僅按字串排序即可得到按時間順序排列的結果。
最大的區別在於「是否可按生成時間排序」。UUID v4 是完全隨機的 128 位值,無法按生成順序排序;而 ULID 的前 48 位是以毫秒為單位的時間戳,僅通過字串比較就能得知生成順序。此外表示形式也不同:ULID 為 26 個字元的 Base32,UUID 則為 36 個字元(含連字元)的十六進位制數。
如果主鍵使用像 UUID v4 這樣完全隨機的值,新行在索引中的插入位置會是隨機的,容易導致 B-tree 索引碎片化並降低快取效率。由於 ULID 具有按時間順序排列的特性,新行往往會被追加到索引末尾附近,因此據說能緩解這一問題。
前 10 個字元是 48 位的毫秒級時間戳(可表示至西元約 10889 年),其餘 16 個字元是 80 位的隨機值。總計 128 位,與 UUID 的位數相同,但同時內含時間資訊,這正是 ULID 的特點。
閒話 ― 把「時間順序」帶入 ID 世界的 ULID
ULID 規範由 Alizain Feerasta 於 2016 年釋出。當時 UUID 早已是分散式系統中生成唯一 ID 的標準手段,但其「完全隨機因而無法排序」的特性,在資料庫索引效率和日誌的時間序列分析上頗為不便,ULID 正是為解決這一問題而誕生的。
事實上 UUID 也存在包含時間資訊的變體,例如版本 1(MAC 地址+時間戳)以及 2024 年標準化的版本 7(時間戳+隨機值的組合)。但 ULID 是獨立於 UUID 規範(RFC 4122)之外的獨立標準,其特點在於追求更簡單的設計以及基於 Base32 的緊湊表示形式。
如今,幾乎所有主流程式語言都有 ULID 的實現庫,它被廣泛應用於分散式系統的事件 ID、日誌的追蹤 ID、資料庫主鍵等需要保留生成順序的場景。它與同時期出現的 UUID v7 在設計理念上有諸多重合之處,二者作為「可排序的類 UUID 識別符號」這一共同課題的不同解法而並存。