Utilo

UUID v4 vs UUID v7 vs ULID:どのユニークIDを使用するべきですか?

ランダム UUID v4、タイムオーダー UUID v7 と ULID をデータベースキー、API、分散システムに対して、パフォーマンス、プライバシー、フォーマットのトレードオフで比較する。

· 8 分で読めます

自動増分の整数は何十年もの間デフォルトのプライマリキーでした。コンパクトで高速ですが数字を配分し数々の記録を漏洩し多数のシステムからデータを統合するのは困難です。グローバル・ユニーク・IDはこれらの問題を解決しますどんなサーバーやモバイル・アプリやオフライン・クライアントでも衝突しないIDを作成できます。問題はどの種類か。このガイドでは,2026年に最も人気のある3つのオプションを比較します UUID バージョン 4、UUID バージョン 7、ULID

UUID の速やかなリフレッシュ

UUID (Universally Unique Identifier) は128ビット値で、通常,5つのグループに分けられた32桁の十六進数で記述される。

550e8400-e29b-41d4-a716-446655440000

現在の標準であるRFC 9562 (RFC 4122を置き換える2024年に公開) は、いくつかのバージョンを定義している。数ビットでバージョンと変数をコードし、残りはバージョンに依存します。V4とV7を一目で区別できます。この3つのグループには、

UUID v4: 純粋にランダム

バージョン4 UUID には 122 つのランダムビットとバージョンと変数の 6 つの固定ビットが含まれます。

優位性

  • すべての言語やデータベースには JavaScript の crypto.randomUUID() や PostgreSQL の gen_random_uuid() のような機能が組み込まれています
  • タイムスタンプも機械の識別子も配列もありません
  • 衝突の確率はほとんどない。複製の確率が50%になるのです複製の確率も50%になります

弱点について

  • ランダムな順序がデータベースのインデックスを傷つけます。PostgreSQL、MySQL、SQL Server で使用されている B ツリーインデックスは、新しいキーが順番を順番に到着するときに最もうまく機能します。ランダムキーがインデックス中に落ちてページが分割されキャッシュの位置が悪くなって書き込みが増幅されます。大型テーブルでは、挿入処理量は大幅に低下し、インデックスは必要以上に大きくなります。
  • 作成時間によって並べられませんので年代順のクエリには別々の created_at 列が必要です

UUID v7: 時間順序で

バージョン7は、48 ビット UNIXタイムスタンプを前面にミリ秒で配置し、その後 74 ビットランダム化 (一部の実装では、同じミリ秒以内に順序付けするためのカウンターとして使用する) しています。

01928c3e-5b7a-7c4d-9f3e-2a1b4c5d6e7f
└─timestamp─┘ └version 7

優位性

  • 新しいIDは大きく増えているので挿入は自動増幅キーのようにインデックス末尾に追加されます。この方法により、インデックスがコンパクトになり、書き込みが速くなります。
  • 作成時間によるIDのソートによるソート、カーソルベースのページ付けをシンプルにする: WHERE id > :last_id ORDER BY id LIMIT 50。
  • これは依然として標準 UUID で、既に UUID を受け入れているネイティブ uuid 列、ORM、API に適合します。
  • IDから作成時間をデバッグするために抽出できます。

弱点について

  • 作成時間はIDを見るすべての人に見える。大半の記録では無害ですがプライバシーに敏感な製品でのユーザーアカウントなどでは誰かが登録した時の情報を公開します
  • 極めて正確な時計が必要です。大きな時計回転が後退すると、既存のIDよりも早くソートするIDが作れます。良い図書館は単調なカウンターで処理します。
  • ネイティブ生成機能は新しいものです。PostgreSQL 18 は uuidv7() を追加した.古いバージョンでは、アプリケーションコードで生成する。

ULID: 整理可能でコンパクトなテキスト

ULID (Universally Unique Lexicographically Sortable Identifier) は UUID v7より前に存在し、同じアイデアを使用しています。48 ビットミリ秒タイムスタンプが80 ビット随意に続く。違いはテキスト形式ですクロックフォードベース32の 26文字です

01J9Z3K8M2Q7X4V5B6N8P0R2T4

優位性

  • UUID文字列より短く URLが安全です
  • 大小文字に敏感で、曖昧な文字 (I、L、O、U) を除外しているため、大声で読むかタイプするのが簡単です。
  • 辞書文字列のソートメントは、鍵値ストアやログファイル名などのテキストとしてIDを格納するシステムで役立つ時間順のソートメントに等しい。

弱点について

  • UUIDではないため、変換なしでネイティブ UUID 列型に適合しない (その 128 ビットは 1 つに格納できる)。
  • IETF標準ではなくコミュニティの仕様で、ライブラリ間の動作が少し異なります。
  • V7のように創造の時間を暴露します

横の比較

資産 UUID v4 UUID v7 ULID
サイズ 128ビット 128ビット 128ビット
テキストの長さ 36 36 26
定時 違う そうだ そうだ
流出作成時間 違う はい (ms) はい (ms)
スタンダード RFC 9562 について RFC 9562 について コミュニティスペック
ネイティブ DB タイプ uuid uuid 通常はテキストまたはバイナリ
インデックスに適した挿入物 貧しい 良かった 良かった

貯蔵のヒント

16バイトで保存しますテキストではなく。36文字の文字列は 2倍以上のスペースを占めていて参照するすべてのインデックスと外国鍵はコストを倍増します。PostgreSQLにはネイティブの uuid タイプがあります。MySQL ユーザーは BINARY(16) と UUID_TO_BIN(uuid, 1) を使用できます。ここで第2の引数は v1 時間スタンプの再排序 v7 のための v1 時間スタンプは、既に時間排序されているため、デフォルトの排序を使用します。

標準的なテキスト形式で API のID を公開します。クライアントはそれらを不透明な文字列として扱って決して意味を解析すべきではありません

セキュリティ上の考慮

このIDは秘密じゃない。パスワードリセットトークンやセッション識別子として使わないでください。v4 UUID は、測り切れないほどのランダム性を持っているが、v7 と ULID は、有効エントロピーを減らす予測可能なタイムスタンプ前置詞を持っている。秘密の場合は、暗号生成器で少なくとも 128 のランダムビットを生成し、パスワードのように処理し、理想的にはハッシュのみを保存します。

また、数値化も考慮してください。/orders/1001と/orders/1002を推測することができます。ランダムまたは時間順序のIDは、それを非現実的にしますが、それらはすべての要求の許可のチェックを代替するものではありません。

どちらを選ぶか?

  • 新しいシステムにおけるデータベースプライマリキー: UUID v7。完全な UUID 互換性も得られます
  • 作成時間がプライベートでなければならない公開識別子: UUID v4 または別々のランダムな公開IDと組み合わせた v7 内部キー。
  • テキストベースのストア、ファイル名、IDは以下のように入力できます: ULIDは短く小字母に敏感でない形式です。
  • ** v4 の既存のシステムでパフォーマンス上の問題がある:** 新しいテーブルでは v7 を考慮してください.両方が有効な UUID であるため、一列のバージョンを混合することは技術的に問題ありません。

ID を生成する

速度の高い作業では、シードデータ、テスト装置、マニュアル挿入ブラウザベースの [UUID生成器] (/tools/uuid) は、crypto.getRandomValues を使用して一度に最大1000v4、v7またはULID値を生成できます。アプリケーションコードでは、自分の言語の標準ライブラリや整備されたパッケージを使って、可能な限りレコード作成に近い ID を生成してください。

まとめ

UUID v4はランダムでプライベートですがデータベースインデックスを分散します。UUID v7はタイムスタンププレフィックスを追加し、標準 UUID に留まる間、挿入を速くし、ID をソートすることができます。ULID は、より短く、より友好的なテキスト形式で同じ順序を提示しています。ほとんどの新しいアプリケーションでは、UUID v7 がベストで、タイムリングが隠されなければならないとき v4 と、人間やテキストベースのシステムがIDを処理するときに ULID を選択します。

このページは英語から自動翻訳されています。誤りを見つけた場合はお知らせください。

関連ガイド