コンテンツにスキップ

UUID vs 連番ID:Tech Leadの提案に同意するか?

問題

Tech Lead tells you: "Let's use UUID everywhere instead of auto-increment IDs." Will you agree?

解答

「用途によって使い分ける」が正解。UUID を一律に使うことには同意しない。

解説

UUID のメリット

メリット 詳細
グローバル一意性 DBをまたいでもIDが衝突しない
分散生成可能 DB を経由せずアプリ側で生成できる
順序が推測不可能 セキュリティ上 ID の列挙攻撃を受けにくい
マイクロサービス向き 複数サービスをまたぐエンティティの識別に便利

UUID のデメリット(重要)

デメリット 詳細
サイズが大きい 16バイト(vs auto-increment の 4〜8バイト)= インデックスが膨張
ランダムな挿入 B-tree インデックスのページ分割が多発し 書き込みパフォーマンスが低下
人間に読みにくい デバッグ・ログ確認が辛い
ソートができない 作成順に並べたい場合は別カラムが必要

パフォーマンス比較(概算)

-- auto-increment: 順次挿入 → B-tree の末尾に追記 → 高速
INSERT INTO users(id, name) VALUES (1001, 'Alice');

-- UUID v4: ランダム挿入 → B-tree の中間ページに挿入 → ページ分割多発
INSERT INTO users(id, name) VALUES ('a3f4...', 'Alice');

大量データ(100万件以上)では UUID の挿入速度は auto-increment より 最大 50% 遅くなる ことがある。

実務での使い分け

┌─────────────────────────────────────────────────────┐
│ 内部結合キー(JOIN の対象)    → auto-increment      │
│ 外部公開 API の識別子         → UUID(推測不可能)   │
│ 分散システムをまたぐ ID        → UUID v7(ソート可能)│
│ 単一 DB、小〜中規模テーブル   → auto-increment      │
└─────────────────────────────────────────────────────┘

UUID v7(2023〜)という解決策

UUID v7 はタイムスタンプ順に並ぶ UUID。UUID v4 のランダム性問題を解消しつつ、グローバル一意性を保つ。

// UUID v7: 先頭 48bit がミリ秒タイムスタンプ
// → B-tree への順次挿入が可能
// → auto-increment に近い書き込みパフォーマンス
import "github.com/google/uuid"

id, _ := uuid.NewV7()
// 例: 018f7b2c-1234-7abc-def0-123456789abc
//      ↑タイムスタンプ部分(時系列順)

面接でのポイント

  • 「同意するか?」系の質問は「場合による」が最強の入り口: 無条件に同意・反対するエンジニアより、トレードオフを整理できるエンジニアが評価される
  • パフォーマンスの数字を出す: 「UUID はページ分割を引き起こす」という理由を B-tree の仕組みと絡めて説明できると強い
  • UUID v7 の存在を知っているとプラス: 最新の標準を把握していることをアピールできる