UUIDとは — v4の仕組み・衝突確率・使いどころ

UUID(Universally Unique Identifier)は、中央のID発番サーバを使わずに、各所が独立して生成しても実用上ぶつからない一意な識別子です。128 ビットの値を 8-4-4-4-12 の36文字で表記し、分散システムの主キーやログの相関IDなどに広く使われます。本記事では UUID の表記・バージョンの違い・v4 の構造衝突確率・使いどころを正確に整理します。

結論を先に:用途を選ばない一般的な一意識別子なら乱数ベースの v4、データベースの主キーのように生成順に並んでほしいなら時刻順の v7 が基本の選択肢です。どちらも暗号論的に安全な乱数(CSPRNG)で作ることが前提になります。

1. UUID とは — 128ビットと 8-4-4-4-12 の表記

UUID は 128 ビット(16 バイト)の値です。人が読み書きしやすいよう、16進数 32 桁をハイフンで区切り、8-4-4-4-12 の 5 ブロック・合計 36 文字で表します。

例:550e8400-e29b-41d4-a716-446655440000

このうち、特定の位置のニブル/ビットが「バージョン」と「バリアント」を表すために予約されています。残りが実際のデータ(v4 なら乱数)に使われます。

2. UUID のバージョンの種類

UUID には複数のバージョンがあり、何を元に値を作るかが異なります。代表的なものを示します。

生成の元特徴・備考
v1時刻 + ノード(MAC アドレス等)時刻順だが MAC を埋め込むためプライバシー上の懸念がある
v3名前空間 + 名前(MD5)同じ入力から常に同じ UUID を生成(決定的)
v4乱数最も一般的。122 ビットが乱数。実装が簡単で偏りがない
v5名前空間 + 名前(SHA-1)v3 の SHA-1 版。決定的に生成したいとき向き
v7時刻(ミリ秒)+ 乱数RFC 9562 で追加。時刻順に単調増加し DB キーに向く

迷ったら、用途を選ばない一般的な ID には v4、データベースの主キーなど順序性が欲しいなら v7 を選ぶ、と覚えておけば十分です。

3. v4 の構造 — 122ビットの乱数・version・variant

v4 は 128 ビットのうち、固定で予約される一部のビットを除いた 122 ビットがランダムです。予約ビットは次の 2 つです。

つまり 36 文字のうち、必ず特定位置に 48/9/a/b が現れます。例で位置を確認します。

例:f47ac10b-58cc-4372-a567-0e02b2c3d479

逆に言えば、3 ブロック目が 4 で始まらない UUID は v4 ではありません。version ニブルと variant ビットを 2 ビット・2 ビットで差し引いて、合計 6 ビットが固定、残り 122 ビットが乱数になります。

4. 衝突確率 — 誕生日問題で考える

「乱数なら、いつか同じ値が出るのでは?」という疑問は当然です。これは誕生日問題(同じ誕生日のペアが現れる確率)の枠組みで見積もれます。

v4 の乱数空間は 2 の 122 乗(約 5.3×1036)通りです。誕生日問題の近似では、おおよそ生成数 n が空間の平方根、すなわち 2 の 61 乗(約 2.3×1018、約 10 京)個に達したあたりで衝突が現実的な確率になり始めます。

ただし前提があります。この見積もりは乱数が真にランダム(一様)であることが条件です。質の悪い乱数源を使うと値が偏り、見積もりよりはるかに早く衝突します。だからこそ、次に述べる「安全な乱数(CSPRNG)」が決定的に重要です。
UUID は Math.random() で作らない。JavaScript の Math.random() は暗号用途を想定しておらず、予測可能で偏りも生じ得ます。ブラウザでは crypto.randomUUID()、それが使えない環境では crypto.getRandomValues()、Node.js では crypto モジュールを使ってください。

5. 使いどころ — 分散システム・相関ID・ファイル名

UUID の強みは「中央集権の発番なしに、独立して一意な値を作れる」ことです。具体的な使いどころを挙げます。

6. v4 と v7 の比較 — インデックス局所性

データベースの主キーに UUID を使う場合、v4 と v7 の違いが性能に効いてきます。v4 は完全にランダムなため挿入位置が毎回バラバラで、B-Tree インデックスのページがあちこちで更新され(断片化・キャッシュ効率の低下)ます。v7 は先頭がミリ秒タイムスタンプで時刻順に単調増加するため、新しい行がインデックスの末尾付近にまとまり、局所性が高いのが利点です。

観点v4(乱数)v7(時刻 + 乱数)
並び順不規則(ランダム)生成順に単調増加
インデックス局所性低い(挿入が分散)高い(末尾付近に集中)
生成時刻の漏えいしない先頭から推測できる
主な用途汎用の一意識別子DB 主キー・時系列キー
標準RFC 4122 / 9562RFC 9562

順序が外部に見えても問題なく、挿入性能を優先したいなら v7、生成時刻すら隠したい・とにかく一様にばらけてほしいなら v4、と用途で選び分けます。

Free Tool UUID Generator で実際に作る ブラウザ内で安全な乱数を使って UUID を生成し、コピーできます。version/variant の位置を含む正しい形式で出力します。

よくある質問(FAQ)

UUID v4 は本当に重複しないのですか?

絶対に重複しないという保証はありませんが、v4 は 122 ビットの乱数を持つため、実用上は衝突をほぼ無視できます。誕生日問題で考えても、衝突が現実的な確率で起き始めるには 2 の 61 乗(約 10 京)個ものUUIDを生成する必要があり、通常のシステムでは到達しません。前提として、暗号論的に安全な乱数(CSPRNG)で生成することが重要です。

v4 と v7 はどちらを使うべきですか?

用途によります。一般的な一意識別子としては乱数ベースの v4 が無難です。一方、データベースの主キーのように生成順に並んでいてほしい場合は、先頭にミリ秒タイムスタンプを置く v7 が向いています。v7 は時刻順に単調増加するため B-Tree インデックスの局所性が高く、挿入性能やページ分割の面で有利です。

UUID は安全な乱数で作られていますか?

実装に依存します。v4 の品質は乱数源の品質に直結するため、必ず暗号論的に安全な乱数生成器(CSPRNG)を使ってください。ブラウザなら crypto.randomUUID() や crypto.getRandomValues()、Node.js なら crypto モジュールが該当します。Math.random() は予測可能で暗号用途に適さないため、UUID の生成に使ってはいけません。

← 技術ブログ一覧へ戻る