Skapa två partiella index :
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;
På så sätt kan det bara finnas en kombination av (user_id, recipe_id)
där menu_id IS NULL
, effektivt implementera den önskade begränsningen.
Möjliga nackdelar:
- Du kan inte ha en främmande nyckel som refererar till
(user_id, menu_id, recipe_id)
. (Det verkar osannolikt att du skulle vilja ha en FK-referens som är tre kolumner bred - använd PK-kolumnen istället!) - Du kan inte basera
CLUSTER
på ett partiellt index. - Frågor utan en matchande
WHERE
condition kan inte använda det partiella indexet.
Om du behöver en komplett index kan du alternativt släppa WHERE
villkor från favo_3col_uni_idx
och dina krav upprätthålls fortfarande.
Indexet, som nu omfattar hela tabellen, överlappar den andra och blir större. Beroende på typiska frågor och procentandelen NULL
värden kan detta vara användbart eller inte. I extrema situationer kan det till och med hjälpa att bibehålla alla tre indexen (de två partiella och en total överst).
Detta är en bra lösning för en enkel nullbar kolumn , kanske för två. Men det går snabbt ur händerna för mer eftersom du behöver ett separat partiellt index för varje kombination av nullbara kolumner, så antalet växer binomalt. För flera nullbara kolumner , se istället:
- Varför utlöses inte min UNIKA begränsning?
Bortsett från:Jag rekommenderar att du inte använder identifierare med blandade skiftlägen i PostgreSQL.