
UUID v1 / v4 / v7 の使い分け — RFC 9562 に基づく実用ガイド
UUID(Universally Unique Identifier)は IETF の RFC 9562(2024年5月、旧 RFC 4122 を廃止・更新)で定義される 128 ビット識別子です。長らく使われてきた v1 / v4 に加え、2024 年の改訂でv6 / v7 / v8 が正式に標準化されました。本記事では各版のビット構造と、どのケースでどれを選ぶべきかを整理します。
UUID の基本構造
UUIDは常に128ビット(16オクテット)で、標準の表記は 8-4-4-4-12 の 16 進数(例: 550e8400-e29b-41d4-a716-446655440000)です。
RFC 9562 は構造を次の領域に分割します:
- version: ビット48〜51の4ビット(標準文字列表記では13番目の16進数字)。1〜8がバージョン番号
- variant: ビット64から始まる可変長フィールド。RFC 9562で主に扱うvariantは上位2ビットが
10で、文字列表記では17番目の16進数字が8〜bになる - 残りの122 ビット: バージョンごとに意味が変わる
つまりversion付きUUIDの種類は13番目のニブルで判別できます。550e8400-e29b-41d4-... の "4" が v4、"7" なら v7 です。NIL UUIDとMax UUIDは通常のversion付き形式ではありません。
v1 — 時刻とnode識別子
v1 は 1582年10月15日(グレゴリオ暦の基準日)からの 100ns 単位のタイムスタンプ 60 ビットと、ノード識別子(通常はMACアドレス)48ビットで構成されます。
time-low : 32bit ←低位ビット
time-mid : 16bit
time-hi : 12bit + version(4bit)
clock-seq: 14bit + variant(2bit)
node : 48bit ←MACアドレスまたは乱数
利点: 値からタイムスタンプを復元でき、node識別子とclock sequenceを組み合わせて一意性を保つよう設計されています。ただしタイムスタンプの各部分が時刻順に並んでいないため、標準文字列や128ビット値をそのまま辞書順に並べても、長期間の生成時刻順にはなりません。この並びを改善したのがv6です。
欠点: node識別子に実MACアドレスを使う実装では、生成元に関する情報を漏らすリスクがあります。RFC 9562は乱数または擬似乱数によるnode IDも認めていますが、利用ライブラリの方式を確認します。
v4 — ランダムベース
RFC 9562のvariantを使うv4では、version 4ビットとvariant 2ビットを除く122ビットを無相関なランダム値または擬似ランダム値で生成します。最も単純な選択肢の一つです。
衝突確率: 122ビットの乱数空間は約 5.3 × 10³⁶ 通りです。独立一様に10億個を生成したと仮定した誕生日問題の近似値は約 9.4 × 10⁻²⁰ です。実際の安全性は、乱数生成器の品質と実装が仕様どおり122ビットを生成することにも依存します。
利点: 実装が単純で、値自体に生成時刻やnode識別子を埋め込みません。
欠点: 時刻順序がないため、Bツリーでは挿入位置が広く散らばります。ページ分割やキャッシュ効率への影響は、データベース、インデックス構造、書き込み負荷によって異なります。
v7 — Unix時刻プレフィックス + 一意性フィールド
v7はRFC 9562で標準化された、Unix時刻を先頭に置く時刻順UUIDです。時刻と無関係なv4よりBツリー等で局所性を得やすい設計ですが、実際の効果はデータベース、インデックス、書き込み負荷で変わります。
unix_ts_ms : 48bit ←Unix時刻(ミリ秒)
version : 4bit (= 7)
rand_a : 12bit ←乱数または単調性用フィールド
variant : 2bit (= 10)
rand_b : 62bit ←乱数または単調性用フィールド
上位48ビットがUnix時刻のため、埋め込まれたミリ秒値が異なるUUIDは、符号なし128ビット値またはRFCのバイト順で比較すると時刻順に並びます。標準文字列でも、16進文字の大文字・小文字を統一し、文字のコードポイント順と整合する照合順序で比較する場合は同じ順序になります。データベースのUUID型なら文字列照合の影響は避けられますが、製品固有の比較順序を確認し、必要ならRFCのバイト順を保つバイナリ値で比較してください。同一ミリ秒内の生成順まで保証するには、実装がサブミリ秒値やカウンター等の単調化方式を採用する必要があります。これにより:
- Bツリー上で新しい値が近い領域へ集まりやすく、ランダムなv4より局所性を得やすい
- UUIDの比較や、生成側が埋め込んだタイムスタンプをおおまかな順序付け・範囲絞り込みに利用できる。ただし埋め込み時刻は業務・監査上の正確な時刻ではないため、厳密な時刻が必要なら別の
created_atやイベント時刻を保存する - 残り74ビットを乱数にでき、必要なら一部をサブミリ秒値やカウンターへ割り当てられる
RFC 9562は、可能ならv1 / v6よりv7を使うことを推奨しています。これはv4を常に置き換えるという意味ではありません。生成時刻を含み、時刻順の局所性が必要ならv7、時刻を含めたくないならv4が候補です。正式公開済みのPostgreSQL 18は、v7を生成する uuidv7() と時刻を抽出する uuid_extract_timestamp() を標準機能として提供しています。
v6 と v8 は何者か
v6: v1の60ビットタイムスタンプを最上位側から時刻順に並べ直した版です。v1形式との変換や既存の時刻・clock sequence・node情報を活用したい用途が対象ですが、nodeにMACアドレスを使えばv1と同じプライバシー上の注意が残ります。RFC 9562は、可能ならv1 / v6よりv7を推奨しています。
v8: 実験的・ベンダー固有の用途向けに、122ビットをカスタム定義できる形式です。versionとvariant以外の意味、一意性、衝突耐性はRFC 9562が保証しません。標準UUIDと同程度の性質が自動的に得られるわけではないため、用途、ビット配置、漏えいし得る情報を独自仕様として管理できる場合に限って検討します。
NIL UUID と Max UUID
RFC 9562 は 2 つの特殊 UUID を定義します。
- NIL UUID: 全ビット 0 (
00000000-0000-0000-0000-000000000000) — "未設定"のセンチネル値 - Max UUID: 全ビット 1 (
ffffffff-ffff-ffff-ffff-ffffffffffff) — RFC 9562 で新規追加。範囲の上限として使える
これらは通常のversion付き形式ではなく、RFC 9562が明示的に定義する特殊形式です。NILを未設定値として使う、Maxを範囲比較の上限として使う、といった意味付けはアプリケーション側の契約で決めます。
用途別の選択指針
表が収まらない場合は、左右にスクロールできます。
| 用途 | 推奨 | 理由 |
|---|---|---|
| DB の主キー(MySQL/PostgreSQL/SQL Server) | v7 | 時刻順の局所性を得やすい。実際の性能はDB・インデックス・負荷で要検証 |
| 公開 API のリソースID | v4 または v7 | 時刻を公開したくなければv4、時刻順が必要ならv7。どちらも認可とは別 |
| セキュリティトークン | 専用トークン | UUIDを認証秘密として流用しない。UUIDが必須ならCSPRNGで生成したv4を最低条件にする |
| 分散システムのログ相関ID | v7 | 時系列で追いやすい。重複防止は生成ライブラリと保存側でも確認 |
| レガシーシステム互換 | v1 / v4 | 既存実装が広く対応しているため |
| 独自のプレフィックス情報を埋め込みたい | v8 | ビット割り当てをカスタマイズ可能 |
実装時の落とし穴
- 文字列保存 vs ネイティブ型・16バイト表現: ハイフン付きASCII文字列は36文字、UUID本体は16バイトです。ただし実際の格納量とインデックス性能はDBの型・照合順序・ページ構造で変わります。PostgreSQLの
uuid型や、MySQLのバイナリ格納を検討し、変換方法まで統一してください。 - 同一ミリ秒内の順序: 74ビットをすべて独立一様乱数にする実装では、同一ミリ秒内の辞書順は生成順になりません。順序保証が必要なら、RFC 9562のサブミリ秒値・カウンター・monotonic randomのどれを実装するライブラリか、時計の巻き戻りや並行生成をどう扱うかを確認してください。
- v4 の乱数品質:
Math.random()は暗号論的に安全ではありません。ブラウザならcrypto.randomUUID()、Node.js ならcrypto.randomUUID()、Python ならuuid.uuid4()を使いましょう。
まとめ
- RFC 9562(2024)が現行仕様。旧 RFC 4122 は廃止
- version は13番目のニブルで即判別できる
- v1: 時刻とnode、標準表現は時刻順でない / v4: 122ビットの乱数、時刻を含まない
- v7: 48ビットUnixミリ秒時刻 + 74ビット。時刻順の局所性が必要なDB主キー等で有力
- v6はv1の時刻フィールドを並べ替えた形式、v8は性質を独自定義するカスタム形式
- NIL UUID(全0) / Max UUID(全1) は境界値として有用
- 暗号乱数APIを使い、可能ならバイナリで保存
参考文献・ソース
記事作成に関する注記
本記事は AI(大規模言語モデル)を編集補助として活用して作成しています。 公開前に編集者が内容を確認していますが、事実誤認・仕様の解釈ミス・最新情報との齟齬が含まれる可能性があります。 重要な判断を行う際は、本文中の一次ソースや公式ドキュメントを必ずご自身でご確認ください。 誤りにお気づきの場合は、お問い合わせフォームよりご連絡いただけると助かります。




