後で編集された一意のインデックス。
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NULL
一意のインデックスには、問題を引き起こす可能性のある少なくとも 2 つの副作用があります。
- 他のテーブルでは、「フィードバック」を参照する外部キー制約を設定できません。
primary key
外部キー参照では、列の組み合わせをまたはとして宣言する必要がありますunique
。
- 一意のインデックスでは、「deleted_at」タイムスタンプのみが異なる複数の行が許可されます。したがって、次の例のような行になる可能性があります。これが問題になるかどうかは、アプリケーションに依存します。
例
user_id subject_id sale_id deleted_at
--
1 1 1 2012-01-01 08:00:01.33
1 1 1 2012-01-01 08:00:01.34
1 1 1 2012-01-01 08:00:01.35
PostgreSQL は、この種のインデックスを部分インデックスとして文書化しています。他のプラットフォームでは、別の用語が使用されます。フィルター処理されたインデックスは 1 つです。部分インデックスのペアを使用すると、問題をある程度制限できます。
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NULL
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_not_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NOT NULL
しかし、特に外部キーに関する潜在的な問題を考えると、これほど面倒なことをする理由はないと思います。あなたのテーブルがこのように見える場合
create table feedback (
feedback_id integer primary key,
user_id ...
subject_id ...
sale_id ...
deleted_at ...
constraint unique_user_subj_sale
unique (user_id, subject_id, sale_id)
);
必要なのは、{user_id、subject_id、sale_id} に対する一意の制約だけです。さらに、完全な削除を行う代わりに、すべての削除で「deleted_at」列を使用することを検討することもできます。