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 つのコンポーネントに分割されます:

タイムスタンプランダム
01ARZ3NDEKTSVE4RRFFQ69G5FAV
48 ビット——Unix タイムスタンプ(ミリ秒)。1ms 精度で生成時刻をエンコードします。10889 年まで対応します。80 ビット——暗号学的に安全なランダムデータ。各 ULID に対して新鮮に生成されます(単調モードを使用しない限り)。

26 個の Crockford Base32 文字としてエンコードされます:最初の 10 文字がタイムスタンプを、最後の 16 文字がランダムコンポーネントを表します。

Crockford Base32 アルファベット

ULID は 36 個の英数字のうち 32 個を使用する Crockford の Base32 エンコーディングを使用します。アルファベット:0123456789ABCDEFGHJKMNPQRSTVWXYZ

なぜこの 32 文字ですか?
0123456789ABCDEFGHJKMNPQRSTVWXYZ

4 つの文字が意図的に除外されています:

  • IL は除外——数字 1 と混同しやすい
  • O は除外——数字 0 と混同しやすい
  • U は除外——生成された ID に偶発的な不適切な言葉が含まれるのを避ける
  • エンコーディングは大文字小文字を区別しない——01ARZ3NDEKTSV4RRFFQ69G5FAV01arz3ndektsv4rrffq69g5fav は同じ ULID

Crockford Base32 は 16 進数より効率的(32 記号 vs 16 記号)で、Base64 より人間が読みやすい(+ / = 文字なし、大文字小文字を区別しない)。

ULID vs UUID

ULID と UUID はどちらも 128 ビット識別子を表しますが、エンコーディングと設計目標において大きく異なります:

プロパティULIDUUID
フォーマット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 セーフ識別子を生成しますが、異なる設計目標を持ちます:

プロパティULIDNanoID
タイムスタンプはい——48 ビット Unix ミリ秒いいえ
ソート可能はいいいえ
デフォルト長26 文字21 文字
エントロピー80 ビット(ランダムコンポーネント)〜126 ビット
アルファベットCrockford Base32(32 文字)URL セーフ Base64(64 文字)
カスタマイズ可能な長さいいえはい(任意の長さ)
ユースケース時間順 ID、DB 主キーランダムトークン、短縮 URL、API キー

時間順序が必要な場合は ULID を選択してください。短いランダム文字列で最大エントロピーが必要な場合は nanoid を選択してください。

データベースでの ULID の使用

ULID は要件に応じていくつかの方法でデータベースに保存できます:

CHAR(26) として保存
最もシンプルなアプローチ。辞書順が保持されます。バイナリストレージよりわずかに大きいですが、人間が読めてデバッグしやすいです。
BINARY(16) として保存
ULID を 16 バイトのバイナリ表現にデコードしてコンパクトに保存します。アプリケーションコードでのエンコード/デコードが必要です。ソート順は保持されます。
PostgreSQL
CHAR(26) として保存するか、バイナリストレージに bytea 型を使用します。ネイティブの ULID 型はありませんが、CHAR(26) の辞書順ソートは正しく機能します。
MySQL / MariaDB
効率的なストレージには CHAR(26) CHARACTER SET ascii を使用します。BINARY(16) でのバイナリストレージも機能し、スペースを節約します。
SQLite
TEXT として保存します。ULID の辞書設計により、SQLite のデフォルトのテキスト比較で ULID が正しくソートされます。
MongoDB
文字列フィールドとして保存します。ULID の辞書ソート可能性は MongoDB の文字列比較と自然に機能します。

コード例

ULID の生成には ulid ライブラリが必要です(JavaScript、Python、Go、Rust などで利用可能):

JavaScript (ulid npm)
// 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)
Python (python-ulid)
# 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
PostgreSQL
-- 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;
JavaScript (pure — no dependencies)
// 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)
}

よくある質問

ULID はグローバルに一意ですか?
はい——非常に高い確率で。80 ビットのランダムコンポーネントは毎ミリ秒毎ジェネレーターあたり 2^80 ≈ 1.2 × 10^24 の可能な値を提供します。異なるジェネレーター間での同一ミリ秒内の衝突確率は、実際のシステムでは無視できるほど小さいです。厳格な一意性保証のためには、同一ミリ秒内に生成された ID のランダムコンポーネントをインクリメントする単調モードを使用してください。
ULID は UUID と同じですか?
いいえ——ULID と UUID は 128 ビット値の異なるエンコーディングです。ULID は UUID フォーマット(ハイフン付き 16 進数)を検証するシステムで UUID の直接の代替として使用できません。ただし、必要に応じてバイナリ ULID と UUID 表現の間で変換することができます。
ULID の単調モードはどのように機能しますか?
標準モードでは、80 ビットのランダムコンポーネントは各 ULID に対して新鮮に生成されます。単調モードでは、同一ミリ秒内に複数の ULID が生成される場合、2 番目以降の ID のランダムコンポーネントは前のランダム値に 1 を加えたものになります。これにより、単一ジェネレーター上のミリ秒内での厳格な単調順序が保証されます。
ULID をデコードして生成タイムスタンプを取得できますか?
はい。最初の 10 個の Crockford Base32 文字が 48 ビットの Unix ミリ秒タイムスタンプをエンコードします。Crockford Base32 アルファベットを使用してこれらの文字をデコードし、結果をミリ秒単位の Unix タイムスタンプとして解釈し、日付に変換します。このツールはまさにそれを行います。
ULID は公式標準ですか?
いいえ。ULID は ulid.github.io で管理されているコミュニティ仕様です。UUID のような IETF 標準ではありません。つまり、参照する公式 RFC がなく、実装によってわずかに異なる場合があります。UUID v7(RFC 9562、2024 年)は同様の時間順プロパティを持つ IETF 標準化された代替手段です。