sql >> Databáze >  >> RDS >> PostgreSQL

Vytvořte jedinečné omezení s prázdnými sloupci

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.



  1. Úrovně kompatibility a primer pro odhad mohutnosti

  2. Obraťte v Oracle tuto cestu z/y/x na x/y/z

  3. sql group pouze po řádcích, které jsou za sebou

  4. Maximální délka MySQL a GROUP_CONCAT().