テーマ: sql
-
PostgreSQLでのtsvectorを使った全文検索
PostgreSQLは、言語設定を使ってテキストを正規化された語彙素(lexeme)からなる`tsvector`に変換し、それを`tsquery`と照合し、`ts_rank`でスコアを付け、GINでインデックスを作成する。ステミングとストップワードの処理は標準で行われるが、タイプミスや同義語には標準では対応しない。
-
PostgreSQLで派生データを保存する:生成列とマテリアライズドビュー
生成列はその行だけから各行の値を1つ導き、仮想型(読み取り時に計算)か保存型(書き込み時に計算)で、不変な式だけを使えます。マテリアライズドビューは任意のクエリ結果を保存し、鮮度は最後のREFRESHまでです。索引を付けたい行ごとの正規化には保存型生成列、遅延を許せる高コストの集計にはマテリアライズドビュー、どちらも合わない場合には維持更新する集計表を使います。
-
Upsert, row limits and identifier quoting across PostgreSQL, MySQL, SQLite and SQL Server
PostgreSQL's ON CONFLICT, MySQL's ON DUPLICATE KEY UPDATE, SQLite's PostgreSQL-style ON CONFLICT and SQL Server's MERGE are three families of upsert syntax, LIMIT/OFFSET has at least three shapes, and a quoted identifier means double quotes, backticks or square brackets depending on the engine.
-
NULL in SQL: three-valued logic and its traps
NULL means unknown, so comparisons with NULL yield unknown rather than true or false; WHERE filters drop unknown rows, NOT IN with a NULL matches nothing, and aggregates skip NULLs. Use IS NULL, IS DISTINCT FROM and COALESCE deliberately.
-
WITH による共通テーブル式と再帰クエリ
WITH は文の残りの部分で使うサブクエリに名前を付けます。WITH RECURSIVE は非再帰項を評価した後、新しい行がなくなるまで再帰項を繰り返し、任意の深さの木やグラフを一つのクエリでたどります。一度だけ参照する副作用のない CTE は、MATERIALIZED を指定しなければ外側のクエリに統合され、SEARCH と CYCLE が順序と循環を扱います。
-
PostgreSQLのプランナー統計:統計ターゲット、列の相関、推定の誤り
プランナーは ANALYZE が標本から得る列ごとの統計、例えば最頻値、ヒストグラム、異なる値の数から行数を推定し、列の独立性を仮定します。古い統計、偏った列の少なすぎる統計項目、列の相関、式が誤推定の原因です。対象列の統計ターゲットを上げ、相関列や式に拡張統計を作り、再分析して推定行数と実際の行数を比較します。
-
Reading a PostgreSQL query plan with EXPLAIN ANALYZE
EXPLAIN shows the planner's chosen tree with estimated costs; EXPLAIN ANALYZE runs the query and adds actual times and row counts. Compare estimated with actual rows, find the node with the largest actual time, and check for sequential scans on large tables and misestimated joins.
-
NULL in SQL: dreiwertige Logik und ihre Fallen
NULL bedeutet unbekannt, darum ergibt jeder Vergleich mit NULL weder wahr noch falsch, sondern unbekannt; WHERE verwirft unbekannte Zeilen, NOT IN mit einem NULL trifft nichts, Aggregate überspringen NULL, und ein Unique-Constraint lässt mehrere NULL zu. IS NULL, IS DISTINCT FROM und COALESCE bewusst einsetzen.
-
Savepoints and the aborted-transaction state in PostgreSQL
After any error inside a transaction block PostgreSQL rejects every further command until the block is rolled back; a savepoint set before a risky statement lets ROLLBACK TO SAVEPOINT discard only that part and continue. Use savepoints deliberately and sparingly, and make error handlers roll back instead of retrying on the same connection.
-
Cursor-Pagination statt Offsets: Seiten, die bei Änderungen stabil bleiben
Offset-Pagination lässt die Datenbank alle übersprungenen Zeilen trotzdem berechnen und verschiebt Seiten, sobald dazwischen eingefügt oder gelöscht wird; Cursor- oder Keyset-Pagination fragt «die nächsten 20 nach Schlüssel X», nutzt den Index und liefert jede Zeile genau einmal. Voraussetzung ist eine eindeutige Sortierung, der Preis ist der Verzicht auf Seitenzahlen.
-
Schema conventions for a new PostgreSQL database: names, identifiers, timestamps and text
Decide a handful of conventions before the first migration: lower-case snake_case names that never need quoting, one id strategy applied everywhere, timestamptz for every point in time with created_at on every table, text instead of varchar(n), and explicit NOT NULL and foreign keys; write them down so every later migration follows them.
-
Bulk operations instead of per-row loops: round trips, transactions and COPY
A loop that sends one statement per row pays a round trip, a parse and often a commit per row; a bulk operation sends the set in one statement, one stream or one transaction. PostgreSQL's own guidance is to commit once, use COPY for loads and build indexes after loading; client libraries offer executemany and copy for the same reason.
-
Datenqualitätsprüfungen: Aktualität, Menge, Nullwerte und Eindeutigkeit als Mindestsatz
Vier billige Prüfungen fangen die meisten kaputten Ladeläufe: Ist die Quelle frisch genug, kam eine plausible Zeilenzahl, sind Schlüssel und Kennzahlen gefüllt, ist die erklärte Körnung eindeutig? Jede Prüfung als Abfrage formulieren, die fehlerhafte Zeilen liefert, nach dem Laden und vor dem Veröffentlichen ausführen, Warnung und Blockade trennen.
-
What connection-pool size relative to CPU cores have teams settled on for a PostgreSQL server, and which measurement made them change it?
Open question: the PostgreSQL wiki offers a sizing formula for active connections built around core count and effective spindle count, and the server's max_connections default is typically 100; what pool sizes have teams actually ended up with after tuning, how far from the formula were they, and what evidence (lock waits, queueing at the pooler, CPU saturation, latency) drove each change?
-
Soft deletes versus archive tables
A soft delete keeps the row with a deleted_at marker, so every query must filter it out and every unique constraint must become a partial index; an archive table moves the row out of the live table, so live queries stay simple and history lives in one place. Choose by who reads deleted data and how often, and put the choice into constraints and views rather than into every query.
-
Writing an upsert with INSERT ... ON CONFLICT
INSERT ... ON CONFLICT (columns) DO UPDATE SET ... turns insert-or-update into one atomic statement driven by a unique index: name the conflict target, update only the columns that should change, use EXCLUDED for the proposed row, and add a WHERE that skips no-op updates. MERGE covers the multi-branch cases ON CONFLICT cannot express.
-
N+1クエリ:回数で検出し、バッチ取得で修正する
N個の親行を読み込み、それぞれの遅延ロードされる関連に触れると N+1 回のクエリが発行されます。コストはコードではなくデータとともに増えるため、小さなフィクスチャではテストが通ります。リクエストごとの回数を検証し、不要な遅延ロードを例外にし、単一対象の関連は結合、コレクションは IN による二回目の一括取得で修正します。
-
Normalising to third normal form and choosing when to denormalise
Normal forms remove repeating groups and facts stored in more than one place; third normal form means every non-key column depends on the key and nothing else. Normalise by default for transactional data and denormalise only in named, derived columns whose source of truth stays normalised.
-
PostgreSQLの宣言的制約:CHECK、UNIQUE、ON DELETE付き外部キー
制約はアプリケーションだけでなく、すべての書き込み主体に対して無効な状態をデータベースに拒否させます。行単位のルールには CHECK、必須値には NOT NULL、一意性には UNIQUE、外部キーには明示的な ON DELETE 動作を使います。参照動作の選択と参照元列の索引作成が、特に見落とされがちです。
-
pg_stat_statements でコストの大きい SQL 文を見つける
pg_stat_statements は、サーバー全体の呼び出し回数、実行時間、ブロック数を正規化した SQL 文ごとに集計します。shared_preload_libraries で読み込み、total_exec_time と calls でそれぞれ順位付けし、平均と最大値を比較してバッファー列を確認します。上位の文を EXPLAIN ANALYZE で調べ、queryid で変更前後を比較します。
機械可読: JSON