AI Session Notes - 2026-03-24
UUIDの基礎知識と実践的な使い分け
学んだこと
- UUIDは「誰がいつどこで生成しても世界中で重複しないID」(128ビット、16進数32桁)
- 主なバージョンの違い:v1(タイムスタンプ+MACアドレス)、v4(完全ランダム)、v7(タイムスタンプ+ランダム、2024年にRFC 9562で標準化)
- UUIDv4の衝突確率は約 1/2^122 で、毎秒10億個生成しても衝突まで数十億年かかる計算
詳細
UUIDはデータベースの連番ID(auto increment)と違い、中央の採番機構なしに一意なIDを生成できる。分散システムやマイクロサービスでは、各サービスが独立してIDを生成する必要があるため、連番IDではなくUUIDのような仕組みが求められる。
RailsでのUUID利用
学んだこと
- Railsではマイグレーションで
create_table :users, id: :uuidとするだけで主キーをUUIDにできる - 主キーをUUIDv4にすると
User.firstが作成順ではなくUUIDの辞書順で返る(UUIDv7なら時間順になるので直感通り動く) - 外部キーにも
type: :uuidの指定が必要
UUIDのパフォーマンス特性とB-treeインデックス
学んだこと
- UUIDv4は完全ランダムなため、B-treeインデックスへの挿入がバラバラのページに散る → キャッシュミスとページスプリットが頻発する
- 連番IDは常にインデックス末尾への追加になるため、キャッシュ効率が良い
- この問題は主キーのインデックスでもサブカラムのインデックスでも構造的には同じだが、影響範囲が異なる
- 主キー:全てのJOIN・外部キー参照・ソートに影響 → 影響大
- サブカラム:そのカラムでの検索時のみ影響 → 影響小
- UUIDv7は時間順に生成されるため、連番IDに近いインデックス性能が出る
詳細
数十万レコード程度ではほぼ体感差はないが、数百万〜数千万レコードになるとUUIDv4の主キーではINSERT性能に差が出始める。ただし「実測して問題になってから最適化する」のが鉄則。
UUIDの実践的な設計パターン
学んだこと
- 「とりあえずUUID」は良くない判断。解決したい課題(ID推測防止、分散生成)があるかどうかで決める
- 多くのWebアプリでは連番IDで十分
- 現実的なパターンとして「内部は連番ID + 外部公開用にUUIDサブカラム」の構成が有効
- 内部処理(JOIN、外部キー、集計)は連番IDで高速に
- 外部公開(API、URL)はUUIDで推測不可能に
- 分散システムでは連番ID自体が使えない(中央の採番機構がボトルネック・単一障害点になる)ため、UUIDv7やSnowflake ID等の「時間順+分散生成可能」な方式を使う
UUID衝突時の対応方針
学んだこと
- DB側のUNIQUE制約が衝突への対応そのもの。衝突するとINSERTがエラーになりデータは入らない(データ整合性は守られる)
- アプリケーション層でのリトライロジックは不要(実行される確率がほぼゼロのデッドコードになる)
- 衝突時のユーザー向けエラーハンドリングも特別なものは不要。サーバーのメモリ故障やディスク障害と同程度の確率の異常事態なので、通常の500エラーと同じ扱いでよい
- 設計レビューで聞かれたら「UNIQUE制約で保護、衝突確率は2^122分の1なのでアプリ層での対応は不要」と説明できればOK
参考リンク
- 【完全入門】UUIDとは?仕様や種類についてすぐ分かる大切な話
- UUIDとは(わわわIT用語辞典)
- UUIDの基本的なところについてまとめてみる(Qiita)
- What are UUIDs and which version should you use?(KINTO Tech Blog)
- UUIDv7 vs UUIDv4 違いをまとめてみた(Zenn)
メタ情報
- ツール: Claude Code
- 関連技術: UUID, PostgreSQL, Rails, ActiveRecord, B-tree, 分散システム