データ

UUIDガイド:v4とv7の違い、データベースの主キーにUUIDを使うときのポイント

550e8400-e29b-41d4-a716-446655440000 のような文字列は、注文、ファイル、APIリクエストなどあらゆる場所で識別子として使われています。UUIDがどのように生成されるのか、どのバージョンを選ぶべきかを学びましょう。

UUIDとは

UUID(Universally Unique Identifier)は128ビットの識別子で、中央のサーバーに問い合わせなくても、誰もが重複しないIDを作れるようにするものです。MicrosoftではGUIDと呼ばれます。現在の標準は2024年に公開されたRFC 9562です。

16進数32桁をハイフンで 8-4-4-4-12 のグループに区切り、合計36文字で表記します。3つ目のグループの先頭の数字がバージョンを表し、xxxxxxxx-xxxx-4xxx-... ならv4、7xxx ならv7です。

バージョンの早見表

現在は、一般用途にはv4、データベースの主キーのように並び順や挿入性能が重要な場合にはv7を選ぶのが一般的です。

  • v1:タイムスタンプとマシンのMACアドレスを組み合わせる。時間順に並ぶが、ハードウェア情報が漏れるおそれがある。
  • v3とv5:名前空間と名前をハッシュするため、同じ入力からは常に同じUUIDが得られる(v3はMD5、v5はSHA-1)。
  • v4:122ビットのランダム値。最も広く使われ、実装も最も簡単。
  • v7:48ビットのミリ秒単位Unixタイムスタンプの後にランダムビットが続く。作成順に並ぶ。

UUIDは本当に衝突しないのか

v4 UUIDのランダム部分は122ビットで、約5.3 × 10^36 通りの値があります。誕生日問題で計算すると、重複が1つ起きる確率が50%になるには約2.7 × 10^18 個のUUIDが必要です。毎秒10億個を85年間作り続ける量で、実際には衝突は起きません。

ただし、これは乱数が本当にランダムな場合に限ります。乱数生成器の状態が同じまま仮想マシンを複製した場合や、予測可能な乱数関数を使った自作実装で重複が報告されています。プラットフォーム標準のUUID関数を使いましょう。

主キーとしてのUUID

UUIDのキーは複数のサーバーで同時に生成でき、レコード数も明かしません。自動採番の整数だと、/orders/1052 のようなURLから競合他社に注文数を推測されてしまいます。

代償はサイズと順序です。UUIDは16バイトで、8バイト整数の2倍あり、36文字の文字列で保存するとさらに大きくなります。v4は完全にランダムなので、新しい行がB-treeインデックスのあちこちに挿入され、ページ分割が頻発して書き込みが遅くなります。v7は時間とともに増加するため、この問題をほぼ避けられます。

  • PostgreSQL:ネイティブの uuid 型(16バイト)を使う。
  • MySQL:BINARY(16) で保存する。8.0以降は UUID_TO_BIN が使える。
  • SQL Server:uniqueidentifier 型を使う。

UUIDを秘密の値に使うべきでない場合

UUIDは一意な名前として設計されたもので、推測できない秘密の値ではありません。v1とv7にはタイムスタンプが含まれるため、一部のビットは予測可能です。パスワード再設定トークンやAPIシークレットのようにセキュリティが重要な値は、十分な量の暗号学的に安全なランダムバイトから生成すべきです。

AIBIZAPのUUID生成ツールで必要な数だけUUIDを作り、秘密の値にはクライアント認証情報生成ツールを使いましょう。JSONのサンプルからテーブルを設計するなら、JSON DDL生成ツールも合わせて使うと便利です。

このツールで試してみましょう

その他のガイド

すべてのガイド