ULIDジェネレーター
Generate lexicographically sortable unique IDs
「生成」をクリックして ULID を作成
ULID とは何ですか?
ULID(Universally Unique Lexicographically Sortable Identifier)は 128 ビットの識別子フォーマットで、一意かつ自然にソート可能なように設計されています。完全にランダムな UUID v4 とは異なり、ULID は上位ビットにミリ秒精度の Unix タイムスタンプを埋め込み——後で生成された ID が前に生成された ID の後にソートされることを保証します。
ULID は Crockford の Base32 アルファベットを使用してエンコードされ、URL セーフで大文字小文字を区別せず、視覚的にあいまいな文字を含まないコンパクトな 26 文字の文字列を生成します。
ULID 仕様は Alizain Feerasta によって作成され、一意性と時間順序の両方が重要な分散システム、イベントソーシング、およびデータベースの主キーで広く使用されています。ULID は IETF 標準ではありません——ulid.github.io のコミュニティ仕様です。
ULID の構造
ULID は 128 ビット幅で、2 つのコンポーネントに分割されます:
| タイムスタンプ | ランダム |
|---|---|
| 01ARZ3NDEK | TSVE4RRFFQ69G5FAV |
| 48 ビット——Unix タイムスタンプ(ミリ秒)。1ms 精度で生成時刻をエンコードします。10889 年まで対応します。 | 80 ビット——暗号学的に安全なランダムデータ。各 ULID に対して新鮮に生成されます(単調モードを使用しない限り)。 |
26 個の Crockford Base32 文字としてエンコードされます:最初の 10 文字がタイムスタンプを、最後の 16 文字がランダムコンポーネントを表します。
Crockford Base32 アルファベット
ULID は 36 個の英数字のうち 32 個を使用する Crockford の Base32 エンコーディングを使用します。アルファベット:0123456789ABCDEFGHJKMNPQRSTVWXYZ
4 つの文字が意図的に除外されています:
IとLは除外——数字1と混同しやすいOは除外——数字0と混同しやすいUは除外——生成された ID に偶発的な不適切な言葉が含まれるのを避ける- エンコーディングは
大文字小文字を区別しない——01ARZ3NDEKTSV4RRFFQ69G5FAVと01arz3ndektsv4rrffq69g5favは同じ ULID
Crockford Base32 は 16 進数より効率的(32 記号 vs 16 記号)で、Base64 より人間が読みやすい(+ / = 文字なし、大文字小文字を区別しない)。
ULID vs UUID
ULID と UUID はどちらも 128 ビット識別子を表しますが、エンコーディングと設計目標において大きく異なります:
| プロパティ | ULID | UUID |
|---|---|---|
| フォーマット | Crockford Base32 | ハイフン付き 16 進数 |
| 長さ | 26 文字 | 36 文字 |
| タイムスタンプ | 48 ビット Unix ミリ秒 | なし(v4)または 48 ビットミリ秒(v7) |
| ソート可能 | はい——辞書順 | いいえ(v4)/ はい(v7) |
| URL セーフ | はい(英数字のみ) | はい(ハイフン付き) |
| 依存関係 | ライブラリが必要 | ネイティブ(crypto.randomUUID) |
| DB サポート | CHAR(26) または BINARY(16) として保存 | ネイティブ UUID カラム型 |
| 仕様 | コミュニティ仕様(ulid.github.io) | RFC 4122 / RFC 9562 |
すでに UUID エコシステム(PostgreSQL uuid カラム、REST API、UUID サポートのある ORM)にいる場合は通常 UUID v7 が ULID より適しています。より人間にやさしいエンコーディングを好みスタック全体を制御する場合は、ULID は優れた選択肢です。
ULID vs nanoid
ULID と nanoid はどちらも短い URL セーフ識別子を生成しますが、異なる設計目標を持ちます:
| プロパティ | ULID | NanoID |
|---|---|---|
| タイムスタンプ | はい——48 ビット Unix ミリ秒 | いいえ |
| ソート可能 | はい | いいえ |
| デフォルト長 | 26 文字 | 21 文字 |
| エントロピー | 80 ビット(ランダムコンポーネント) | 〜126 ビット |
| アルファベット | Crockford Base32(32 文字) | URL セーフ Base64(64 文字) |
| カスタマイズ可能な長さ | いいえ | はい(任意の長さ) |
| ユースケース | 時間順 ID、DB 主キー | ランダムトークン、短縮 URL、API キー |
時間順序が必要な場合は ULID を選択してください。短いランダム文字列で最大エントロピーが必要な場合は nanoid を選択してください。
データベースでの ULID の使用
ULID は要件に応じていくつかの方法でデータベースに保存できます:
コード例
ULID の生成には ulid ライブラリが必要です(JavaScript、Python、Go、Rust などで利用可能):
// Using the 'ulid' npm package
import { ulid } from 'ulid'
const id = ulid() // "01ARZ3NDEKTSV4RRFFQ69G5FAV"
const id2 = ulid() // "01ARZ3NDEKXXXXXXXXXXXX..." (same ms, incremented random)
// With a custom timestamp
const id3 = ulid(1469918176385) // deterministic time portion
// Extract the timestamp back out
import { decodeTime } from 'ulid'
decodeTime(id) // → 1469918176385 (Unix ms)# Using python-ulid
from ulid import ULID
uid = ULID()
str(uid) # "01ARZ3NDEKTSV4RRFFQ69G5FAV"
uid.timestamp # 1469918176.385
uid.datetime # datetime(2016, 7, 30, 23, 36, 16, 385000, tzinfo=timezone.utc)
# Parse an existing ULID string
parsed = ULID.from_str("01ARZ3NDEKTSV4RRFFQ69G5FAV")
parsed.timestamp # 1469918176.385-- Store ULIDs as TEXT or CHAR(26)
CREATE TABLE events (
id CHAR(26) PRIMARY KEY DEFAULT gen_ulid(), -- if using a PG extension
name TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Or pass the ULID from your application layer
INSERT INTO events (id, name, created_at)
VALUES ('01ARZ3NDEKTSV4RRFFQ69G5FAV', 'user.signup', NOW());
-- Range queries are efficient because ULIDs sort chronologically
SELECT * FROM events
WHERE id > '01ARZ3NDEKTSV4RRFFQ69G5FAV'
ORDER BY id
LIMIT 20;// Pure browser / Deno / Node.js implementation (no dependencies)
const CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
function encodeTime(ms) {
let result = '', n = BigInt(ms)
for (let i = 9; i >= 0; i--) {
result = CROCKFORD[Number(n & 31n)] + result
n >>= 5n
}
return result
}
function encodeRandom(bytes) {
let n = 0n
for (const b of bytes) n = (n << 8n) | BigInt(b)
let result = ''
for (let i = 15; i >= 0; i--) {
result = CROCKFORD[Number(n & 31n)] + result
n >>= 5n
}
return result
}
function generateULID() {
const randomBytes = new Uint8Array(10)
crypto.getRandomValues(randomBytes)
return encodeTime(Date.now()) + encodeRandom(randomBytes)
}