2つの部分インデックスを作成します :
CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;
CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;
このように、(user_id, recipe_id)
の組み合わせは1つだけです。 ここで、menu_id IS NULL
、必要な制約を効果的に実装します。
考えられる欠点:
-
(user_id, menu_id, recipe_id)
を参照する外部キーを持つことはできません 。 (3列幅のFK参照が必要になる可能性は低いようです。代わりにPK列を使用してください!) -
CLUSTER
をベースにすることはできません 部分インデックス上。 - 一致する
WHERE
のないクエリ 条件は部分インデックスを使用できません。
完全が必要な場合 インデックスの場合は、代わりにWHERE
を削除することもできます favo_3col_uni_idx
からの条件 そして、あなたの要件は引き続き適用されます。
現在、テーブル全体を構成しているインデックスは、他のインデックスと重複し、大きくなります。一般的なクエリとNULL
の割合によって異なります 値、これは役立つ場合と役に立たない場合があります。極端な状況では、3つすべてのインデックス(2つの部分的なインデックスと合計が一番上)を維持するのに役立つ場合もあります。
これは、単一のnull許容列に適したソリューションです。 、多分2人用。ただし、null許容列の組み合わせごとに個別の部分インデックスが必要になるため、すぐに手に負えなくなり、数は2倍に増えます。 複数のnull許容列の場合 、代わりに参照してください:
- UNIQUE制約がトリガーされないのはなぜですか?
余談ですが、PostgreSQLでは大文字と小文字が混在する識別子を使用しないことをお勧めします。