PostgreSQL ドキュメント
モデルが間違えやすい PostgreSQL 18 ドキュメントのルール:驚くべきデフォルト、ロックと並行性のトラップ、PostgreSQL 18 の変更点、およびドキュメントが推奨するパターン。各ルールの末尾に、それを裏付けるドキュメントの URL が付いています。
対象バージョン
参照は PostgreSQL 18 のドキュメント(マイナーリリース 18.6)に従います。18 からしか有効でない事実には「PostgreSQL 18」と記載します。まずサーバーバージョンを確認してください。古いサーバーでは、「PostgreSQL 18」と記載されたルールはすべて利用不可として扱ってください。
ナビゲーション方法
以下のテーブルから、タスクに必要な参照のみを読んでください。ソース:SOURCES.md。
クイックルール
- PostgreSQL 18 では、キーワードなしの generated カラムは VIRTUAL(読み取り時に計算)になります。統計情報や論理レプリケーションには
STOREDと記述してください。 https://www.postgresql.org/docs/18/ddl-generated-columns.html https://www.postgresql.org/docs/18/sql-altertable.html serialではなく identity カラムを使用してください。identity カラムは NOT NULL ですが一意ではありません。PRIMARY KEY を追加してください。 https://www.postgresql.org/docs/18/ddl-identity-columns.html- 外部キーの参照側カラムには自分でインデックスを作成してください。PostgreSQL は参照される側のみにインデックスを作成します。 https://www.postgresql.org/docs/18/ddl-constraints.html
- 単純な
CREATE INDEXはビルド全体で書き込みをブロックします。ライブテーブルではトランザクションブロックの外でCREATE INDEX CONCURRENTLYを使用し、失敗した場合は残った INVALID インデックスを削除してください。 https://www.postgresql.org/docs/18/sql-createindex.html - 大きなテーブルへの制約追加は
NOT VALIDで行い、その後VALIDATE CONSTRAINTを実行してください。これは書き込みをブロックしません。PostgreSQL 18 では NOT NULL に対してもこれが有効です。 https://www.postgresql.org/docs/18/sql-altertable.html ADD COLUMNで揮発性のデフォルト値、STORED generated カラム、または identity を使用すると、テーブル全体が ACCESS EXCLUSIVE で書き換えられます。非揮発性のデフォルト値では書き換えは発生しません。 https://www.postgresql.org/docs/18/sql-altertable.html- マイグレーションセッションでは
lock_timeoutを設定し、statement_timeout、lock_timeout、transaction_timeoutはロールまたはセッションごとに設定し、決してグローバルに設定しないでください。 https://www.postgresql.org/docs/18/runtime-config-client.html - アップサートは
INSERT ... ON CONFLICT (cols) DO UPDATEを使用してください。これは READ COMMITTED では常に挿入または更新を並行して行います。MERGE は別のセッションが同じキーを挿入すると一意制約違反で失敗する可能性があります。 https://www.postgresql.org/docs/18/transaction-iso.html - SQLSTATE 40001 および 40P01 では、トランザクション全体を再試行してください。PostgreSQL は自動的には再試行しません。メッセージではなく SQLSTATE をテストしてください。 https://www.postgresql.org/docs/18/mvcc-serialization-failure-handling.html
- デフォルトの分離レベルは READ COMMITTED です。各ステートメントは新しいスナップショットを参照します。複数行にわたるビジネスルールには SERIALIZABLE または明示的なロックが必要です。 https://www.postgresql.org/docs/18/transaction-iso.html https://www.postgresql.org/docs/18/applevel-consistency.html
- ジョブキューには
SELECT ... FOR UPDATE SKIP LOCKEDを使用し、キーが変更されない場合はFOR NO KEY UPDATEを使用してください。 https://www.postgresql.org/docs/18/sql-select.html https://www.postgresql.org/docs/18/explicit-locking.html - リストまたはサブクエリに NULL が含まれる
NOT INは常に偽になります。count以外の集計関数は、ゼロ行に対して NULL を返します。 https://www.postgresql.org/docs/18/functions-comparisons.html https://www.postgresql.org/docs/18/functions-aggregate.html - ページングと
LIMITには一意なキーによる ORDER BY が必要です。そうしないと実行ごとに結果が異なります。 https://www.postgresql.org/docs/18/queries-limit.html - 瞬間的な時刻は
timestamptzとして保存してください。TIMESTAMP '2004-10-19 10:23:54+02'はタイムゾーンのないタイムスタンプとなり、オフセットは無視されます。 https://www.postgresql.org/docs/18/datatype-datetime.html now()はトランザクションの開始時刻です。実際の時刻が必要な場合はclock_timestamp()を使用してください。文字列リテラル'now'をデフォルトに使用しないでください。 https://www.postgresql.org/docs/18/functions-datetime.htmljsonbを使用し、@>クエリにはGIN (col jsonb_path_ops)でインデックスを作成してください。インデックスが使用されるためには、演算子がインデックス式に適用される必要があります。 https://www.postgresql.org/docs/18/datatype-json.html- PostgreSQL 18 では、
gen_random_uuid()に加えて、時刻順の UUID を生成するuuidv7()が追加されました。 https://www.postgresql.org/docs/18/functions-uuid.html - PostgreSQL 18 の
RETURNINGは、INSERT、UPDATE、DELETE、MERGE でold.colとnew.colを読み取れます。 https://www.postgresql.org/docs/18/dml-returning.html EXPLAIN ANALYZEはステートメントを実行します。書き込み操作はBEGIN ... ROLLBACKでラップしてください。PostgreSQL 18 では BUFFERS が自動的に含まれます。 https://www.postgresql.org/docs/18/sql-explain.html https://www.postgresql.org/docs/18/using-explain.html- PostgreSQL 18 では、複数列 B-tree インデックスは先頭列なしでもクエリを処理できます(スキップスキャン)が、その先頭列の異なる値の数が少ない場合に限ります。 https://www.postgresql.org/docs/18/indexes-multicolumn.html
- autovacuum は有効にしたままにし、VACUUM FULL は避けてください。autovacuum はパーティションテーブルや一時テーブルを分析しません。これらは自分で ANALYZE してください。 https://www.postgresql.org/docs/18/routine-vacuuming.html
- 行レベルセキュリティは
ENABLE ROW LEVEL SECURITYを実行するまで効果がなく、テーブル所有者はFORCE ROW LEVEL SECURITYがない限りこれをバイパスします。 https://www.postgresql.org/docs/18/ddl-rowsecurity.html - SECURITY DEFINER 関数では、
SET search_path = trusted_schema, pg_tempを設定し、同じトランザクション内で PUBLIC に対する EXECUTE を取り消す必要があります。 https://www.postgresql.org/docs/18/sql-createfunction.html - テーブルへの権限付与は、それが使用するシーケンス(
serialカラムのものを含む)には拡張されません。シーケンスの権限は個別に設定してください。 https://www.postgresql.org/docs/18/sql-grant.html - クライアントはデフォルトで
sslmode=preferを使用し、サーバーを検証しません。sslmode=verify-fullを使用してください。 https://www.postgresql.org/docs/18/libpq-ssl.html - 動的 SQL は
format('%I', ident)と値にはEXECUTE ... USINGを使用して構築し、連結は絶対に行わないでください。 https://www.postgresql.org/docs/18/plpgsql-statements.html - 全文検索の式インデックスは、2 引数の
to_tsvector('english', col)を使用する必要があり、クエリでもその正確な形式を繰り返す必要があります。 https://www.postgresql.org/docs/18/textsearch-tables.html
参照
| 参照 | 読むべき時 |
|---|---|
| schema-design.md | テーブル作成時:identity とシーケンス、generated カラム、制約、時間キー、ドメイン、スキーマと search_path、パーティショニング設計 |
| migrations-and-locks.md | マイグレーション作成時:ALTER TABLE のロックレベルと書き換え、NOT VALID、同時インデックス構築、REINDEX、パーティションのアタッチとデタッチ |
| data-types.md | 数値、テキスト、bytea、enum、UUID、配列、範囲型の選択、範囲に対する排他制約 |
| datetime.md | タイムスタンプ、タイムゾーン、期間、extract、date_trunc、to_char、to_timestamp に関すること |
| json.md | JSONB の保存、クエリ、インデックス作成、更新、jsonpath、JSON_VALUE、JSON_TABLE、JSON 集計関数 |
| queries.md | SELECT のロジック:NULL セマンティクス、結合、LATERAL、グループ化、集計、ウィンドウ関数、ページング、UNION、CTE |
| writes.md | INSERT ON CONFLICT、UPDATE と DELETE の結合、大きな変更のバッチ処理、RETURNING、MERGE、COPY、一括ロード |
| indexes.md | インデックスの選択またはレビュー:型、カラム順序、スキップスキャン、部分、式、INCLUDE、pattern_ops、GIN、BRIN |
| concurrency.md | 分離レベル、再試行、行ロックとテーブルロック、デッドロック、アドバイザリロック、タイムアウト、LISTEN と NOTIFY |
| performance.md | EXPLAIN の読み方、統計情報と拡張統計情報、バキューム、メモリとプランナ設定、パラレルクエリ、pg_stat_statements |
| security.md | GRANT とデフォルト権限、ロール、行レベルセキュリティ、SECURITY DEFINER、パスワード、TLS と libpq 接続パラメータ |
| plpgsql-triggers.md | 関数、PL/pgSQL、動的 SQL、例外、トリガー、プロシージャの作成 |
| text-search.md | 文字列関数、LIKE と正規表現、引用、tsvector による全文検索、ランキング、ts_headline |
アップグレード時に注意すべき PostgreSQL 18 の変更点
initdbはデフォルトでデータチェックサムを有効にし、pg_upgradeは設定が一致する必要があります。 https://www.postgresql.org/docs/18/release-18.html- パーティションテーブルに対する VACUUM と ANALYZE は、そのパーティションも処理します。親のみを対象にするには
ONLYを記述してください。 https://www.postgresql.org/docs/18/release-18.html pg_upgradeはプランナ統計情報を保持しますが、拡張統計情報は保持しません。 https://www.postgresql.org/docs/18/release-18.html- AFTER トリガーは、イベントがキューに入れられたときにアクティブだったロールとして実行されます。 https://www.postgresql.org/docs/18/release-18.html
- 非同期 I/O(
io_method、デフォルトworker)、およびeffective_io_concurrencyのデフォルトは 16 です。 https://www.postgresql.org/docs/18/runtime-config-resource.html
古いパターン
| 古いパターン | 現在のパターン |
|---|---|
デフォルト値のリテラル 'now' または 'today' | now()、CURRENT_DATE (https://www.postgresql.org/docs/18/datatype-datetime.html) |
MD5 パスワード、password 認証方式 | scram-sha-256 (https://www.postgresql.org/docs/18/auth-password.html) |