Vytvořte dva dílčí indexy :
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;
Tímto způsobem může existovat pouze jedna kombinace (user_id, recipe_id)
kde menu_id IS NULL
, efektivně implementovat požadované omezení.
Možné nevýhody:
- Nemůžete mít odkaz na cizí klíč
(user_id, menu_id, recipe_id)
. (Zdá se nepravděpodobné, že byste chtěli referenci FK o šířce tří sloupců – použijte místo toho sloupec PK!) - Nemůžete založit
CLUSTER
na částečném indexu. - Dotazy bez odpovídající
WHERE
podmínka nemůže použít částečný index.
Pokud potřebujete úplné index, můžete alternativně vypustit WHERE
stav z favo_3col_uni_idx
a vaše požadavky jsou stále vynucovány.
Index, který nyní obsahuje celou tabulku, se překrývá s tou druhou a zvětšuje se. V závislosti na typických dotazech a procentu NULL
hodnot, to může, ale nemusí být užitečné. V extrémních situacích může dokonce pomoci zachovat všechny tři indexy (dva dílčí a celkový navrch).
Toto je dobré řešení pro jeden sloupec s možnou hodnotou Null , možná pro dva. Pro více se to ale rychle vymkne z rukou, protože pro každou kombinaci sloupců s možnou hodnotou Null potřebujete samostatný dílčí index, takže číslo roste binomicky. Pro více sloupců s možnou hodnotou Null , místo toho viz:
- Proč se nespustí moje UNIKÁTNÍ omezení?
Stranou:Doporučuji nepoužívat smíšené identifikátory velkých a malých písmen v PostgreSQL.