Avoid UUID Version 4 Primary Keys in Postgres

2025/12/15 19:08

Avoid UUID Version 4 Primary Keys in Postgres

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Summary

PostgreSQL のランダム UUID v4 主キーは、単純な連番整数 ID と比べて性能とストレージに大きな問題を引き起こします。v4 値は非順序であるため、B‑Tree インデックスへの挿入がページ間に散らばり、頻繁なページ分割・断片化、大きめのリーフノード(約 40 % 大きい)、WAL I/O の増加、およびキャッシュヒット率の低下を招きます。研究では、時間順序付き UUID v7 または単純整数 ID へ切り替えることで WAL トラフィックがほぼ半減し、保守負荷も軽減できることが示されています。

UUID は PostgreSQL の

uuid
型で保存される 128‑bit バイナリ値です。RFC 4122 がそのフォーマットを定義していますが、v4 は高負荷下では一意性を保証しないと記載されています。UUID は bigint(8 バイト)に対して 16 バイトのストレージフットプリントを二倍にします。また RFC 4122 セクション 6 により 暗号学的またはセキュリティ目的には安全ではありません

v4 の問題を緩和するには、テーブルの再パック(

pg_repack
pg_squeeze
)や
VACUUM FULL
REINDEX CONCURRENTLY
の実行、大きなメモリバッファ(
shared_buffers
をデータベースサイズの約 4 倍に設定)と
work_mem
のチューニングが必要です。Rails 開発者は
implicit_order_column
を使用するか、順序付き列でクラスタリングして局所性を向上させることもできます。

新規データベースでは 32‑bit または bigint ID を既定に設定してください。v4 を使用している既存テーブルは、新しい行だけ v7 に切り替えることで全データの移行なしに対応可能です。PostgreSQL 18+ はネイティブ

pg_uuidv7
サポートを提供します。連番または時間順序付き ID を採用することで、スケーラビリティが向上し、書き込み遅延が低減し、大規模アプリケーションの運用コストも削減されます。

本文

はじめに

過去10年間、UUID v4 を主キーとして使用するデータベースは、一般的にパフォーマンスの低下と過剰な I/O が問題となってきました。

UUID は PostgreSQL のネイティブ型で 16 バイト(128 ビット)で保存されます。
RFC 4122 では複数のバージョンが定義されており、Version 4 は主にランダムビットから構成されるため、生成時刻や場所を隠蔽します。

PostgreSQL(v13 以降)では

gen_random_uuid()
により UUID v4 を生成できます。
「UUID は安全だ」という誤解もありますが、多くのユーザーは理由に合わないケースでこの型を選択しています。

主張

UUID v4 を主キーとして使用しないこと。
一般的には、正当な代替手段が存在しない限り UUID の利用は避けるべきです。


本投稿の UUID コンテキスト

  • UUID(Microsoft 用語では GUID)は 36 文字の文字列:32 桁の16進数+4 つのハイフンで構成され、128 ビットのバイナリ値として保存されます。
  • RFC 4122 は 128 ビットがどのように設定されるかを規定しています。
  • UUID v4 の値はほぼランダムです。UUID v7 は最初の 48 ビットにタイムスタンプを埋め込み、インデックス性能を向上させます。
  • UUID v7 は PostgreSQL 18(2025 年秋予定)で採用される予定です。

ウェブアプリケーションへの適用範囲

  • PostgreSQL を主な OLTP データベースとするモノリシックウェブアプリ(例:ソーシャルメディア、e‑commerce、クリック追跡、業務プロセス自動化)。
  • これらのシナリオでは、非効率的なストレージと取得がパフォーマンス問題を引き起こします。

UUID v4 の核心的課題

ランダム性はインデックス挙動を悪化させます:

  1. 挿入遅延 – ランダム値は B‑tree 内の任意の位置に配置され、ページ分割や再バランスが整数順序より頻繁に発生します。
  2. 検索コスト – 更新・削除・範囲検索で非連続ページをたどる必要があり、I/O が増大します。
  3. 自然順序の欠如 – キャッシュ効率が低下します。

UUID が有用なケース

  • クライアント側生成 – 複数サービスやデータベースで ID を生成し、衝突を避ける必要がある場合。
  • 分散システム – シャード間で調整なしに一意の ID が必要なとき。
  • 衝突回避 – ランダム v4 UUID は極めて低い衝突確率(≈ 2.71×10¹⁸ 前に 50 % の衝突確率)を持ちます。

RFC 4121 第6節: 「UUID が推測しづらいとは仮定せず、セキュリティ機能として使用してはならない。」


匿名 ID 用の代替策

ランダム UUID の代わりに整数から擬似乱数コードを生成できます:

-- 整数 → バイナリ → キーで XOR → Base62 エンコード

これにより外部に公開される非連続 ID を得つつ、内部キーは整数のままです。


UUID v4 の欠点

問題説明
空間消費16 バイト対
bigint
の 8 バイト。インデックスとテーブルサイズが倍増します。
挿入遅延・断片化ランダム配置により頻繁にページ分割、WAL I/O が増加。
キャッシュヒット率低下ランダムページはバッファミスを多くし、shared_buffers に収まるページ数が減少します。
検索時の I/O 増大B‑tree のリーフ密度が低い(約 79 % 対整数で 98 %)。

実証データ

  • バッファヒット

    • bigint
      インデックス – 27,332 ヒット。
    • UUID v4 インデックス – 8,562,960 ヒット。

    → 約 850 万ページ(約 68 GB)がメモリからアクセスされ、10M 行・1M 更新で 1–3.4 秒の遅延を追加。

  • リーフページ密度 (

    pg_pageinspect
    使用):

インデックス平均リーフ充填率
records_id_idx
97.64
records_uuid_v4_idx
79.06
records_uuid_v7_idx
90.09

緩和策

  1. インデックス再構築
    REINDEX CONCURRENTLY
    pg_repack
    、または
    VACUUM FULL
    を使用。
  2. 十分なメモリ確保 – データベースサイズの 4 倍を RAM に割り当てる(例:25 GB DB → 128 GB インスタンス)。
  3. work_mem
    の増加
    – ソートが多いクエリに対して。
  4. Rails:
    implicit_order_column
    を利用し、UUID ではなく高カードなインデックス付きフィールドで並び替え。
  5. クラスタリング – 可能なら
    created_at
    のような順序付けられた列でクラスタ化。

推奨事項

  • 新規データベース – 小規模アプリは符号付き 32 ビット (
    int4
    )、大規模または成長重視のアプリは
    bigint
    (
    int8
    ) を使用。
  • 既存 UUID v4 テーブル – 移行が可能なら時間順序付けられた UUID(例:UUID v7)への移行を検討。
  • UUID が必須の場合 – 順序付け可能なバージョン(UUID v7 など)を選び、
    gen_random_uuid()
    を主キーに使わない。

要約

  • UUID v4 はランダム性により検索遅延と I/O が増大。
  • bigint
    の2倍の空間を消費。
  • RFC 4121 で「安全ではない」と明記。
  • ランダム UUID はキャッシュヒット率低下・WAL トラフィック増加を招く。
  • 匿名 ID を求めるなら整数から擬似乱数コードを生成。
  • UUID が不可欠な場合は時間順序付けられたバージョン(UUID v7)を使用。

さらに読む

  • Franck Pachot – “UUID in PostgreSQL” (AWS Heroes)。
  • Brandur – “Identity Crisis: Sequence v. UUID as Primary Key”。
  • 5 Minutes of PostgreSQL – “UUIDs vs Serial for Primary Keys”。
  • andyatkinson/pg_scripts PR #20。

更新

  • 2025‑12‑15 – Hacker News フロントページに掲載。
    「ランダム性が問題」というセクションを明確化して更新しました。

同じ日のほかのニュース

一覧に戻る →

2025/12/16 6:37

Fix HDMI-CEC weirdness with a Raspberry Pi and a $7 cable

## Japanese Translation: > **概要:** > Samsung S95B TV(論理アドレス 0x00)、Denon AVR‑X1700H(0x05)、Apple TV、PS5、Xbox Series X、Nintendo Switch 2、および `/dev/cec0` をリッスンする Raspberry Pi 4 が含まれるホームシアター構成で、テレビの入力にのみ切り替えるコンソールが原因となるオーディオルーティング問題を著者は解決します。 > Pi(論理アドレス 0x01)から AVR に「System Audio Mode Request」パケット(`15:70:00:00`)を送信することで、受信機は ARC を有効化し、すべてのコンソールオーディオをテレビではなく自身経由でルーティングします。 > 著者は Python スクリプト `cec_auto_audio` でこれを実装しており、長時間稼働する `cec-client -d 8` を起動し、TRAFFIC 行から Active Source イベント(オペコード 0x82)を解析し、以前に Set System Audio Mode(オペコード 0x72)が検出されていない場合に毎回ウェイク時にパケットを送信します。 > スクリプトは systemd サービス `cec_auto_audio.service` としてパッケージ化され、起動時に開始されます。これにより、多層の HomeKit/Eve オートメーションと比べて低レイテンシで軽量な代替手段を提供します。 > トラブルシューティングガイドには、スキャン(`echo "scan" | cec-client -s`)、トラフィック監視(`cec-client -m`)、および欠落オペコード(0x82, 0x84, 0x70, 0x72)の良いケースと悪いケースの比較が含まれます。 > 残るエッジケースとして、コンソールのスタンバイがテレビチューナーを起動させる場合や HomeKit オートメーションがアクティブなソースなしでテレビをオンにする場合などには、追加の状態機械ロジックが必要になる可能性があります。著者はコミュニティメンバーに対し、より広範なトラブルシューティングのために CEC パケットトレースを共有してもらうよう呼びかけています。

2025/12/11 8:54

Nature's many attempts to evolve a Nostr

## Japanese Translation: **要約** 人気のあるアプリケーションの普遍的な設計は、ユーザーのデータと暗号鍵を所有する単一クラウドサーバーに集中しています(「あなたの鍵がないなら、あなたのデータではない」)。この中央集権化は封建制や寡占構造を生み出します。サーバーは橋を上げてユーザーを切り離す城のような存在です。フェデレーション(例:Mastodon、Matrix)はサーバー間で通信できるようにしますが、鍵とデータは依然としてサーバーの管理下にあり、ネットワーク理論はそのようなフェデレートシステムがスケールフリー分布へ収束し、支配的なハブを生み出すと予測しています。これはGmail/ProtonMail のメール寡占や Facebook Threads の ActivityPub ノードが Fediverse を支配する現象として観察されています。 セルフホスティングは居住IPの禁止やインフラコストにより多くのユーザーが個人サーバーから離れるため、非実用的になります。ピアツーピアネットワークはユーザー所有鍵を提供しますが、拡張性、信頼できないノード、スーパーpeer の中央集権化、複雑な最終的一致メカニズム、および長い多ホップルーティング遅延に悩まされます。 Nostr プロトコルは「リレーモデル」を提案します。単純で信頼できないリレーは署名されたメッセージを転送するだけで、相互通信しません。これにより \(N^2\) スケーリング問題を回避します。ユーザーは数個(通常 2–10)のリレーユーザーに購読し、自分のデータと鍵を完全に制御でき、リレーが失敗または停止した場合でも信頼性高く離脱できます。広く採用されれば、これはユーザーに真の所有権と単一点障害への耐久性を与え、中央集権サーバーに依存する企業に対し、よりユーザー中心で分散型アーキテクチャとの競争を強いるでしょう。これにより、ソーシャルメディアやメッセージングは真の分散モデルへと再構築される可能性があります。

2025/12/12 15:47

“Are you the one?” is free money

## 日本語訳: --- ## 要約 この記事は、番組「Are You the One?」の参加者が数学モデルを用いて、最終エピソード前にほぼ確実に全ての正しいカップルを推測できる方法を説明しています。戦略的にトゥルーブースとエピソード終了時のマッチアップデータを活用することで達成されます。 - **ゲーム設定**:10人の男性と10人の女性が、色でのみ明らかになる10組の完璧なペアに分けられます。参加者はすべてのペアを正しく推測し、100万ドルを獲得します。 - **情報源**: - *トゥルーブース* は特定のペアが成立しているかどうか(バイナリ結果)を確認します。 - *エピソードマッチアップ* はそのラウンドで正しいペアの総数のみを明らかにします。 「ブラックアウト」エピソード(0件マッチ)は、そのラウンド内のすべてのペアについて否定的な情報を提供し、複数のトゥルーブースと同等の効果があります。 - **モデル**:著者は OR‑Tools の最適化フレームワークを構築し、シーズン開始時に約400万件の有効マッチング(≈4 百万)を追跡し、各イベント後に更新します。シーズン1ではエピソード8でモデルが「解読」されました。 - **情報理論**:各イベントは約1〜1.6ビットの情報量を提供します。シミュレーションでは ~1.23 bits/イベント、実際の番組データでは ~1.39 bits/イベント、最適戦略で最大 1.59 bits/イベントが得られます。全検索空間は約22ビット(10!)を必要とするため、完璧な戦略には平均して約1.1 bits/イベントが十分です。 - **結果**: - ランダムペアリングでは、カップル数に関係なく平均正解スコアは約1になります。 - 100シーズンのランダムシミュレーションでモデルを使用した成功率は74%でしたが、情報理論戦略では98%に上昇します。 - 実際の番組データ(7シーズン)では71%の成功率と約1.39 bits/イベントとなり、純粋なランダムよりわずかに優れていますが、理論的最適値にはまだ届きません。 - **今後の作業**:著者はインタラクティブなウェブツールを開発予定で、ユーザーが異なる戦略を試し、必要な情報ビット数を確認し、実際のデータとパフォーマンスを比較できるようにします。 **影響** 本研究は参加者やプロデューサーに対して効率的な質問設計のための具体的なアルゴリズムフレームワークを提供し、エンターテインメントにおける組合せ最適化とベイズ推論の実用例を示すとともに、研究者にリアルワールドケーススタディとしてさらなる探求の機会を与えます。

Avoid UUID Version 4 Primary Keys in Postgres | そっか~ニュース