- 種類
- バージョン 7:並べ替え可能な Unix 日時
- バリアント
- RFC 9562(旧 RFC 4122)
- 作成日時
- 2022/02/22 16:22:22 2022-02-22T19:22:22.000Z · 1645557742000 ms
017f22e2-79b0-7cc3-98c4-dc0c0c07398f017F22E2-79B0-7CC3-98C4-DC0C0C07398F{017F22E2-79B0-7CC3-98C4-DC0C0C07398F}urn:uuid:017f22e2-79b0-7cc3-98c4-dc0c0c07398f01FWHE4YDGFK1SHH6W1G60EECF017f22e279b07cc398c4dc0c0c07398f1989357241971137676463954034883508623AX8i4nmwfMOYxNwMDAc5jw==仕組み
UUID は 128 ビットの数値で、5 つのグループ(8-4-4-4-12)に分けた 16 進数 32 桁で表記します。値が既に使われているかを誰にも問い合わせずにレコードを識別できるため、2 台のサーバー、2 つのモバイルアプリ、2 つのプロセスが調整なしに同時に識別子を作っても衝突しません。形式は RFC 9562 で定義されており、2024 年に RFC 4122 を置き換え、バージョン 6・7・8 を追加しました。
3 番目のグループの先頭の数字がバージョンを表し、バージョンごとにビットの配置が異なります。バージョン 4 は完全な乱数です。バージョン 7 はミリ秒単位の日時で始まるため、識別子は作成順に並びます。バージョン 3 と 5 にはランダムな要素がなく、名前空間と名前のハッシュから作られるので常に同じ結果になります。バージョン 1 と 6 は 100 ナノ秒精度の日時と、歴史的にはコンピューターの MAC アドレスだったノードを含みます。
解析機能はその逆を行います。バージョンとバリアントを読み取り、v1・v6・v7 の UUID と ULID から日時を復元し、同じ値を GUID、URN、16 進数、整数、Base64 で表示します。すべてブラウザー内で計算され、識別子がサーバーに送られることはありません。
例
v5 · DNS · www.example.com2ed6657d-e927-568b-95e1-2665a8aea6a2RFC 9562 のテストベクターです。バージョン 5 を正しく実装したライブラリなら、DNS 名前空間のこの名前に対して必ずこの値を返します。017F22E2-79B0-7CC3-98C4-DC0C0C07398F2022-02-22T19:22:22.000Zv7 UUID の先頭 12 桁は Unix ミリ秒の 16 進表記です。0x017F22E279B0 は 1645557742000 です。C232AB00-9414-11EC-B3C8-9F6BDECED8461EC9414C-232A-6B00-B3C8-9F6BDECED846同じ時刻をバージョン 1 とバージョン 6 で表したものです。バージョン 6 は日時のビットを上位から下位の順に並べ替え、文字列が時系列順に並ぶようにしています。クロックシーケンスとノードは変わりません。01ARZ3NDEKTSV4RRFFQ69G5FAV01563e3a-b5d3-d676-4c61-efb99302bd5bULID は UUID と同じ 128 ビットを占めるので、uuid 型の列に保存できます。ただしバージョンもバリアントもないため、UUID として読むとその桁は乱数部分の一部になります。ユースケース
- データベースの自動採番を待たずに、クライアントや複数のサービスで同時に主キーを作成する。
- 再試行された支払いや注文が二重に処理されないよう、冪等キーを生成する。
- 各リクエストに相関 ID を付け、複数のマイクロサービスのログを横断して追跡する。
- v5 で自然キー(メールアドレス、URL、SKU)から安定した識別子を導出し、テーブルを共有しなくても 2 つのシステムが同じ値にたどり着くようにする。
- ログやエラーレポートに現れた v7 UUID や ULID から、レコードがいつ作成されたかを知る。
- 数百件の有効な識別子を使ったテストデータを一度に用意する。
よくある質問
主キーには v4 と v7 のどちら?
作成日時を隠す理由がなければ v7 です。B ツリーインデックスはキーを順序どおりに格納しますが、v4 はインデックスのどこにでも入るため、挿入のたびに別のページに触れ、ページ分割が起き、キャッシュ効率も下がります。v7 は自動採番と同じく常に末尾に追加されます。SQL Server には注意が必要で、uniqueidentifier 型は最後の 6 バイトから比較して並べるため、そこでは v7 でも連続になりません。
v4 UUID が重複することはある?
理論上はあり得ますが、実際には起きません。v4 には 122 ビットの乱数があり、少なくとも 1 回重複する確率が 50 % に達するには約 2.7 × 10¹⁸ 個、つまり毎秒 10 億個を 85 年以上生成し続ける必要があります。条件は暗号学的乱数生成器を使うことです。実際に報告される重複は数学ではなく、シードの初期化不備が原因です。
UUID と GUID は同じもの?
はい。GUID は Microsoft が使う名称で、文字列は同一です。Windows では通常、大文字で波括弧に囲まれて表示されます。違いはバイナリ表現にあり、.NET の Guid.ToByteArray は最初の 3 グループをリトルエンディアンで格納するため、そのバイト列を別の言語で読むと先頭の桁が逆順に見えます。
UUID を秘密のトークンとして使える?
正しく生成された v4 には予測不能な 122 ビットがあり、推測されにくいリンクには十分です。しかし RFC 9562 は、UUID は認証情報として設計されていないと明記しています。多くのライブラリは暗号学的乱数生成器を保証しておらず、バージョン 1・6・7 は作成日時を明かしてしまいます。セッションやパスワードリセットのトークンには、専用のランダムバイトを生成するほうが安全です。
ULID と UUID v7 のどちら?
どちらもほぼ同じ情報を持っています。48 ビットのミリ秒と残りの乱数です。ULID はハイフンや紛らわしい文字のない 26 文字で表記され、URL で扱いやすいのが利点です。v7 は標準の UUID なので、変換なしで PostgreSQL の uuid 列やあらゆるバリデーターに収まります。ゼロから始めるならデータベースに uuid 型がある場合は v7 を選びましょう。
v1 UUID のノードが自分の MAC でないのはなぜ?
ネットワークカードの MAC アドレスを公開すると、各識別子をどのマシンが作ったかを追跡できてしまうからです。1999 年に Melissa ウイルスの作者が特定されたのもこの方法でした。RFC 9562 はマルチキャストビットを立てたランダムなノードを推奨しており、このツールもそうしています。v1 UUID に本物の MAC が含まれている場合は解析機能が知らせます。