Как добавить условный уникальный индекс на PostgreSQL - PullRequest
9 голосов
/ 19 января 2012

У меня есть таблица line_items со следующими столбцами:

product_id
variant_id

variant_id обнуляется.

Вот условие:

  • Еслиvariant_id равно NULL, тогда product_id должно быть уникальным.
  • Если значение variant_id имеет значение, комбинация product_id и variant_id должна быть уникальной.

Возможно ли это в PostgreSQL?

Ответы [ 2 ]

26 голосов
/ 19 января 2012

Создать UNIQUE индекс из нескольких столбцов в (product_id, variant_id):

CREATE UNIQUE INDEX line_items_prod_var_idx ON line_items (product_id, variant_id);

Однако, это позволило бы несколько записей (1, NULL) для (product_id, variant_id), поскольку значения NULLне считаются идентичными.
Чтобы восполнить это, дополнительно создайте частичный UNIQUE индекс на product_id:

CREATE UNIQUE INDEX line_items_prod_var_null_idx ON line_items (product_id)
WHERE variant_id IS NULL;

Таким образом, вы можете ввести (1,2)(1,3) и (1, NULL), но ни один из них во второй раз.Также ускоряет запросы с условиями для одного или обоих столбцов.

Недавний, связанный ответ на dba.SE, почти напрямую применимый к вашему случаю:

1 голос
/ 22 сентября 2015

Другой вариант - использовать выражения в ваших ключевых полях.Возможно, этого не было, когда вы задавали вопрос, но это может быть полезно для других, кто сталкивался с этим сейчас.

CREATE UNIQUE INDEX line_items_prod_id_var_id_idx
ON line_items ( product_id, (coalesce(variant_id, 0)) );

Конечно, это предполагает, что ваше variant_id является автоинкрементным целым числом, которое былона 1. Также обратите внимание на круглые скобки вокруг выражения.Согласно документам, они требуются.

http://www.postgresql.org/docs/9.3/static/sql-createindex.html

...