テック技報最新号へ →
インフラ

主キーは連番、外に見せる ID は別カラム(public_id)にする

主キーに UUID を使うと、インデックス・外部キー・JOIN のすべてでサイズが大きくなりキャッシュ効率が落ちる。主キーは 32/64bit の連番にして、URL などで公開する ID は public_id(ランダムな 16 進文字列+ユニーク制約)を別に持つ、という設計。

@kenn · 投稿 2026-01-30
#infra#database#postgres#mysql#設計

どんなときに使う?

  • 新しいテーブル設計で「主キーを UUID にするか連番にするか」迷ったとき
  • 「ユーザーに推測されない ID を使いたい」から UUID にしようとしているとき

設計

sql
CREATE TABLE articles (
  id        BIGSERIAL PRIMARY KEY,        -- 内部用。連番(32bit or 64bit)
  public_id TEXT NOT NULL UNIQUE,         -- 外部公開用。ランダムな hex を入れる
  ...
);
  • public_id にはアプリ側でランダムな 16 進文字列(例: 16 文字)を生成して入れる。投稿者によれば、16 文字は誕生日問題で 50% 衝突確率を基準に考えるとちょうどよく、必要になれば段階的に長くしてよい(16〜32 文字)。
  • 例として YouTube の動画 ID も base62 で 11 文字。

なぜ連番か(投稿の要点)

  • DB 性能設計の最大の要点は「空間効率」。128bit と 32bit で 4 倍違うサイズは、tuple 本体だけでなくインデックス、外部キー、JOIN の比較、CPU キャッシュに乗るかどうかまで効いてきて、最終的に 8 倍・16 倍の差に増幅される。
  • UUIDv7 で挿入の局所性の問題が改善しても、サイズの問題は残る。
  • キャッシュヒット率が落ちると、スケールアップしかできないマスター DB では早い段階でシャーディングが必要になりかねない。

注意点

  • 分散環境で ID を DB の外で採番したい、複数 DB をマージする予定がある、などの事情があれば別の判断になる。
  • 関連: 論理削除をやめて状態ごとにテーブルを分ける設計の記事 @about_hiroppy · 2026-05-29

出典

X の元の投稿を開く