インデックス一意性検査

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 50章インデックスアクセスメソッドのインタフェース定義 | 早送り | 次のページ

# 50.5. インデックス一意性検査

PostgreSQLは、SQLの一意性制約を一意性インデックスを使用して強制します。 このインデックスでは、同一キーに対し複数の項目を許しません。 この機能をサポートするアクセスメソッドは`pg_am`.`amcanunique`を真に設定します。 （現時点ではb-treeのみがこれをサポートします。）

MVCCのため、インデックス内に物理的に重複した項目が存在することができることが常に必要です。 この項目は、1つの論理的な行の連続的なバージョンを示します。 実際に強制させたい動作は、MVCCスナップショットが同じインデックスキーを持つ行を2つ含めないことです。 一意性インデックスに新しい行を挿入する時に検査しなければならない状況を以下のように分割することができます。

- 競合する有効な行が現在のトランザクションで削除された場合は問題ありません。 （具体的には、UPDATEは常に新しいバージョンを挿入する前に古い行バージョンを削除します。 これによりキーを変更することなく行をUPDATEすることができます。）

- 競合する行が未コミットのトランザクションで挿入された場合、挿入しようとしている方はトランザクションのコミットが分かるまで待機しなければなりません。 ロールバックした場合は競合しません。 競合する行が削除されずにコミットした場合、一意性違反となります。 （具体的には、他のトランザクションの終了をただ待機し、終了後に可視性の検査を再実行します。）

- 同様に、競合する有効な行が未コミットのトランザクションで削除された場合、挿入しようとしている方はトランザクションのコミットまたはアボートを待機しなければならず、その後、試験を繰り返します。

さらに、上記規則に従った一意性違反が発声する直前に、アクセスメソッドは挿入される行の有効性を再度検査しなければなりません。 もし、無効なコミットであれば、エラーを発生してはいけません。 （現在のトランザクションによって作成された通常の行の挿入という状況では、これは発生することはありません。 しかし、これは`CREATE UNIQUE INDEX CONCURRENTLY`中に発生することがあります。）

インデックスアクセスメソッドにこうした試験を自身で行うことを要求します。 これは、インデックスの内容に対して重複するキーを持つことを示している任意の行のコミット状態を検査するために、ヒープまでアクセスしなければならないことを意味します。 これが醜くモジュール化されないことには疑う余地はありません。 しかし、余計な作業を防ぐことができます。 もし分離された探査を行ったとすると、新しいインデックス項目を挿入する場所を検索する時、競合する行に対するインデックス検索がどうしても繰り返されます。 さらに、競合検査がインデックス行の挿入部分で統合されて行われない限り、競合状態を防ぐ明確な方法がありません。

この概念の主な制限は、遅延された一意性検査をサポートする簡便な方法が存在しないことです。

前のページ | ホーム | 次のページ
インデックスのロック処理に関する検討 | 上に戻る | インデックスコスト推定関数