Създайте два частични индекса :
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)
където menu_id IS NULL
, ефективно прилагане на желаното ограничение.
Възможни недостатъци:
- Не можете да имате външен ключ, препращащ
(user_id, menu_id, recipe_id)
. (Изглежда малко вероятно да искате препратка към FK три колони широка - вместо това използвайте колоната PK!) - Не можете да базирате
CLUSTER
на частичен индекс. - Заявки без съответстващ
WHERE
условието не може да използва частичния индекс.
Ако имате нужда от пълен index, можете алтернативно да пуснете WHERE
условие от favo_3col_uni_idx
и вашите изисквания все още се прилагат.
Индексът, който сега включва цялата таблица, се припокрива с другия и става по-голям. В зависимост от типичните заявки и процента на NULL
стойности, това може да е полезно или не. В екстремни ситуации може дори да помогне да се поддържат и трите индекса (двата частични и общия отгоре).
Това е добро решение за единична колона с нула , може и за двама. Но той бързо излиза от ръцете за повече, тъй като имате нужда от отделен частичен индекс за всяка комбинация от колони с нула, така че броят нараства биномно. За множество колони с нулеви стойности , вижте вместо това:
- Защо моето ограничение UNIQUE не се задейства?
Настрана:Съветвам ви да не използвате смесени идентификатори в PostgreSQL.