この記事に関連するツール
ブラウザ上ですぐに試せます。記事の内容を確認しながら使うと、作業の流れをつかみやすくなります。
UUIDとは何か
UUID(Universally Unique Identifier) は、コンピューターシステム上で情報を識別するために使われる128ビットのラベルです。RFC 4122(および2024年のRFC 9562)で標準化されており、通常は次のような正規形式で表記されます。

550e8400-e29b-41d4-a716-446655440000
8桁、4桁、4桁、4桁、12桁の16進数をハイフンで区切った、合計36文字(ハイフン4つを含む)の文字列です。
UUIDの根本的な価値は、中央のID管理者と調整することなく、どのマシンでもいつでも生成でき、過去に生成されたどのUUIDとも衝突する確率が天文学的に低いという点にあります。これが、中央集権的なID発行ができない分散システムでUUIDが重宝される理由です。
全バージョン早見表
UUID仕様には複数のバージョンが定義されており、それぞれ生成方式が異なります。
| バージョン | 生成方式 | ソート可能 | 使いどころ |
|---|---|---|---|
| v1 | MACアドレス+タイムスタンプ | 部分的 | レガシーシステム、監査ログ |
| v3 | 名前空間+名前のMD5ハッシュ | 不可 | 既知の入力から決定的なID(旧式) |
| v4 | ランダム | 不可 | 汎用、セッションID |
| v5 | 名前空間+名前のSHA-1ハッシュ | 不可 | 既知の入力から決定的なID |
| v6 | タイムスタンプ+ランダム(v1の再配置) | 可能 | v1の順序付き代替 |
| v7 | UNIXミリ秒+ランダム | 可能 | DB主キー(推奨) |
| v8 | カスタムレイアウト | 場合による | アプリ固有の形式 |
Version 4:定番のランダム
UUID v4は単純に122ビットの暗号学的乱数です(残り6ビットはバージョンとバリアントを示します)。世界で最も多く生成されているUUIDです。
// ブラウザ / Node.js(標準搭載、ライブラリ不要)
const id = crypto.randomUUID(); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
# Python
import uuid
print(uuid.uuid4()) # 3d6f4890-4f40-4d09-aa11-3efb...
// Go
import "github.com/google/uuid"
id := uuid.New()
衝突確率: 毎秒10億個のv4 UUIDを86年間生成し続けても、1回でも衝突する確率はおよそ50%です。実用上、衝突は事実上起こり得ません。
欠点: v4はランダムなのでソートできません。ランダムなUUIDを主キーとしてB-treeインデックスに挿入すると、時間とともにインデックスが断片化し、大規模環境では書き込み性能が低下します。
Version 7:現代の標準
UUID v7はRFC 9562(2024年5月)で標準化されました。最上位ビットにUNIXミリ秒タイムスタンプを置き、その後にランダムデータが続きます。
タイムスタンプが上位にあるため、v7 UUIDは 生成時刻順に辞書順ソート可能 です。連続して生成された2つのUUIDは、文字列比較でその順序にソートされます。これはまさにデータベースのインデックスが求める性質です。
// uuidv7 パッケージを使用
import { uuidv7 } from 'uuidv7';
const id1 = uuidv7(); // "018e1f27-42a0-7000-8000-..."
const id2 = uuidv7(); // "018e1f27-42a1-7000-..."
// id1 < id2(文字列比較で正しい順序になる)
// Go(google/uuid v1.6.0+)
id, err := uuid.NewV7()
Version 1:MACアドレス+タイムスタンプ
UUID v1は生成マシンのMACアドレスと100ナノ秒単位のタイムスタンプをエンコードします。マシンの識別子と時刻の組み合わせが一意になるため、衝突リスクは極めて低いです。
欠点として、MACアドレスは個体を識別できる情報です。Webアプリでv1を生成すると、サーバーのハードウェア情報をうっかり露出してしまう可能性があるため、新規システムでは敬遠されています。
Version 3 / Version 5:決定的なUUID
v3とv5はどちらも、名前空間 UUIDと 名前 文字列からハッシュ関数(v3はMD5、v5はSHA-1)を使ってUUIDを生成します。同じ入力からは常に同じUUIDが得られます。外部データから安定した識別子を作るのに便利です。可能ならMD5より強いSHA-1を使うv5を選びましょう。
UUID と連番整数IDの比較
データベースの主キーでは、従来は自動採番の整数(SERIAL、AUTO_INCREMENT)が定番でした。UUIDはこのトレードオフを変えます。
| 観点 | 自動採番整数 | UUID v4 | UUID v7 |
|---|---|---|---|
| IDの予測可能性 | 推測可能(列挙できる) | 予測不能 | 予測不能 |
| インデックス性能 | 優秀(連番) | 低い(ランダム書き込み) | 優秀(時刻順) |
| 分散生成 | 中央調整が必要 | どのノードでも可 | どのノードでも可 |
| マージ/レプリケーション | 複雑 | 容易 | 容易 |
| 行サイズ | 4〜8バイト | 16バイト | 16バイト |
| 可読性 | 容易 | 困難 | 困難 |
マイクロサービス、マルチリージョン展開、複数ソースのデータ統合を行う現代のシステムでは、主キーには UUID v7 がデフォルトの最適解 です。
実務上の注意点
データベースでの保存
- PostgreSQL: ネイティブの
UUID型を使う。36文字の文字列ではなく16バイトで保存される。 - MySQL/MariaDB: 効率重視なら
BINARY(16)、可読性重視ならCHAR(36)。UUID_TO_BIN(uuid, true)でソート可能性を保てる。 - SQLite:
BLOB(16)またはTEXT(36)。
文字列 vs バイナリ保存
UUIDを文字列("f47ac10b-...")で保存すると36バイト、生のバイナリなら16バイトです。数百万行になると、この差はストレージとインデックスサイズの両方で効いてきます。
試してみる
「UUIDってどんな見た目?」「v4を一気に100個作りたい」。そんなときは UUID生成ツール を使ってみてください。ボタンを押すたびに、一瞬で新しいUUIDが生成されます。
よくある質問
UUID v4 は本当にランダムですか?
UUID v4は122ビットのランダムデータを使います(残り6ビットはバージョンとバリアント用に固定)。「本当に」ランダムかどうかは乱数生成器に依存します。現代の多くの環境は暗号学的に安全な疑似乱数生成器(CSPRNG)を使っており、crypto.randomUUID() はシステムのCSPRNGを使うためセキュリティ用途にも適しています。
既存のv4をすべてv7に移行すべき?
いいえ。既存IDの移行は通常、労力に見合いません。v7の利点(ソート可能性、インデックス局所性)は 新規挿入 に対して効きます。既にv4を使っていてインデックス性能が許容範囲なら、そのままにしましょう。新しいテーブルや新システムからv7を使い始めるのが現実的です。
2台のマシンが同じv4を生成することはありますか?
理論上はあり得ますが、実用上はありません。122ビットのランダム性があるため、50%の衝突確率に達するには約2.7×10¹⁸個のUUIDが必要です。世界中のすべてのマシンが毎秒10億個生成しても、85年以上かかります。
nil UUID とは?
nil UUIDはすべてゼロの 00000000-0000-0000-0000-000000000000 です。「UUIDなし」を示すセンチネル値(null に近い)として使われます。
UUIDの形式を検証するには?
簡単な正規表現でチェックできます。
const UUID_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
UUID_REGEX.test('550e8400-e29b-41d4-a716-446655440000'); // true
UUID_REGEX.test('not-a-uuid'); // false