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