#データベース
38 件の記事
PostgreSQL LISTEN/NOTIFY — どこまで使い、いつメッセージキューへ移行するか
PostgreSQL 内蔵の pub/sub である LISTEN/NOTIFY の実用範囲を整理します。トランザクションと一緒にコミット時点で発行される動作原理、8000 バイトのペイロード上限と「キーだけ送れ」の原則、リスナーがいなければ消える揮発性、大量発行時のコミット直列化ボトルネックという規模の限界、だから定石になる「通知は起動の合図 + 仕事は SKIP LOCKED のテーブルキュー」の組み合わせ、そして本物のメッセージキューへ移る基準まで扱います。
PostgreSQL Row-Level Security — マルチテナント分離を DB で強制する
行単位のアクセス制御(RLS)の実践導入を扱います。WHERE tenant_id の漏れというマルチテナント最悪の事故を、アプリケーションの規律ではなく DB の強制で防ぐ構造、ENABLE ROW LEVEL SECURITY と CREATE POLICY の基本形、current_setting でリクエストごとにテナントを指定する標準パターンとコネクションプールの注意点、性能の条件(tenant_id のインデックス)、そして RLS を使わないほうがいい場合まで扱います。
timestamptz の罠まとめ — PostgreSQL の時刻処理で間違えやすいこと
PostgreSQL の時刻処理の実践的な罠を集めました。timestamptz がタイムゾーンを保存するという誤解、結果がセッションの TimeZone によって違って見える原理、AT TIME ZONE が型によって逆に動く二重性、date_trunc・日付グルーピングが真夜中の基準をどこに置くかで変わる問題、未来の予定は timestamptz だけでは足りない理由(タイムゾーン規則の変更)、now() と clock_timestamp() の違いまで扱います。
UUID vs bigint 主キー — 性能差の実体と uuidv7
主キー論争の定番である UUID vs bigint を、実測できる根拠で整理します。bigint が既定値である理由(サイズ・挿入の局所性・結合コスト)、UUID v4 がインデックスに無作為に挿入されて書き込みとキャッシュ効率を落とす原理、時系列順でその問題をほぼ解消した uuidv7 と PostgreSQL 18 の組み込み関数、uuidv7 に残るトレードオフ(生成時刻の露出・16 バイト)、そして内部 bigint + 外部 UUID の併用設計まで扱います。
N+1 クエリ問題 — 症状、検出、解決まで
ORM を使うサービスが遅くなる最もよくある原因、N+1 クエリを扱います。一覧 1 つにクエリが 101 回飛ぶ構造ができる原理(遅延ロード)、アプリケーションのログと pg_stat_statements の calls で検出する方法、JOIN・IN の一括ロード・ORM の即時ロードオプションという 3 つの解法、そして「画面が必要とするデータをクエリ数ではなく形で設計する」という予防原則まで扱います。
PostgreSQL upsert の定石 — ON CONFLICT の使い方と罠
「あれば更新、なければ挿入」を競合状態なしに処理する ON CONFLICT を扱います。SELECT してから INSERT する方式が同時実行で壊れる理由、DO NOTHING と DO UPDATE の使い方、EXCLUDED で新しい値を参照する方法、衝突判定の対象(ユニーク制約)を明示すべき理由、値が同じでも行がロックされ書き換えられるコスト、MERGE との関係、そしてシーケンスが飛ぶ現象まで扱います。
pgvector 実践 — PostgreSQL でベクトル検索を運用するときに知っておくこと
埋め込み検索を別のベクトル DB を使わずに PostgreSQL で運用する実践ガイドです。vector 型と距離演算子、HNSW インデックスが既定値である理由と IVFFlat との比較、フィルタ条件と一緒に使うときの取りこぼし問題と反復インデックススキャン(0.8.0)、halfvec でサイズを半分にする方法と 4000 次元への対応、そして「専用ベクトル DB が必要になるのはいつか」の判断基準まで扱います。
PostgreSQL vs MySQL — 2026 年に新規プロジェクトならどちらか
2 つのオープンソース RDBMS の選択基準を整理します。結論は「新規プロジェクトは特別な理由がなければ PostgreSQL、すでに MySQL エコシステムの上に立っているなら MySQL を維持」です。MySQL 8.0 サポート終了(2026-04)と 8.4 LTS への移行時期、機能の幅(JSONB・ウィンドウ関数・拡張)と MVCC 実装の違い、レプリケーションのエコシステムの成熟度の差、そしてどちらを選んでもいい場合まで、判断基準を扱います。
PostgreSQL 実践講座 #9 バックアップ・PITR・アップグレード — 障害直前に戻る技術
実践編の締めくくりとしてデータを守る最後の層を扱います。pg_dump の論理バックアップの限界を超える物理バックアップ(pg_basebackup)と WAL アーカイブの組み合わせ、望む時刻へ巻き戻す PITR(Point-In-Time Recovery)の原理と復旧目標の設定、「削除事故はフェイルオーバーでは戻せない」というレプリケーションとバックアップの役割の区別、メジャーバージョンアップグレードの 3 つの道(pg_dump・pg_upgrade・論理レプリケーション)、そしてトラック全体の振り返りまで扱います。
PostgreSQL 実践講座 #8 レプリケーションと高可用性 — ストリーミングレプリケーション、読み取り分散、フェイルオーバー
DB サーバー 1 台の限界を超える標準手段、レプリケーションを扱います。WAL をそのまま流すストリーミング(物理)レプリケーションの原理、非同期レプリケーションのレプリケーション遅延と read-your-writes 問題、同期レプリケーションのトレードオフ、読み取り負荷をスタンバイに分散するときの注意点、自動フェイルオーバーに必要なもの(Patroni など)とスプリットブレイン、テーブル単位で選んで送る論理レプリケーションの用途、そしてマネージドサービスとの対応関係まで扱います。
PostgreSQL 実践講座 #7 パーティショニング — 巨大テーブルを時間の単位で分ける
数億行テーブルの標準処方である宣言的パーティショニングを扱います。パーティショニングが実際に解決する問題(古いデータの削除が DROP 一発・パーティションプルーニング・VACUUM 負担の分散)と解決しない問題、RANGE パーティショニングで月別テーブルを作る文法、パーティションキーが PK に含まれる必要がある制約、プルーニングが効くクエリ条件の条件、新しいパーティションを作り続ける運用負担と pg_partman、そして「いつ導入するか」の判断基準まで扱います。
PostgreSQL 実践講座 #6 ロックと同時実行 — デッドロック、DDL ロック、SKIP LOCKED
MVCC が解決してくれない領域、ロックを扱います。行ロック(書き込み同士の衝突)とテーブルロック(DDL)の 2 つの層、ロック待ちを pg_locks と pg_blocking_pids で追跡する方法、デッドロックが起きる構造(交差した順序の更新)と予防ルール(同じ順序で取る)、SELECT FOR UPDATE で読んで-判断して-書くを安全にする方法、そして作業キューの標準パターン FOR UPDATE SKIP LOCKED まで扱います。