Например, @lad2025 прокомментировал, status
действительно должен быть boolean
. Дешевле, чище.
В любом случае вы можете навязать свое правило с помощью частичного уникального индексаа>:
Чтобы разрешить ноль или одну строку с status = 'Active'
во всей таблице:
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';
Чтобы разрешить ноль или одну строку с status = 'Active'
на userid
, сделайте userid
индексируемым столбцом:
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';
Обратите внимание, что userid IS NULL
не вызовет уникальных нарушений, потому что два значения NULL никогда не считаются равными. userid
в этом случае должно быть set NOT NULL
.
Почему индекс, а не ограничение?
Ответ на ваш вопрос в комментарии: это индекс, а не CONSTRAINT
.
Индекс для первого случая крошечный, содержит одну строку или не содержит ее.
Индекс для второго случая содержит одну строку для каждого существующего userid
, но это < em>самый дешевый и быстрый способ, а также чистый и безопасный. В любом случае вам понадобится индекс для проверки других строк, чтобы сделать это быстро.
Вы не можете иметь проверку ограничения CHECK
для других строк - по крайней мере, не в чистом и надежном виде. Есть способы, которые я бы не рекомендовал в этом случае:
Если вы используете ограничение UNIQUE
для (userid, status)
(которое также реализуется с помощью уникального индекса в фоновом режиме!), вы не можете сделать его частичным, и все комбинации принудительно уникальный. Вы можете по-прежнему использовать это, если работаете с status IS NULL
во всех случаях, кроме случая 'Active'
. Но на самом деле это потребует гораздо большего индекса, включающего все строки.
person
Erwin Brandstetter
schedule
28.12.2015
IsActive
логического типа вместо храненияVARCHAR
или, если у вас больше статусов, используйте тип INT и добавьте таблицу поиска. - person Lukasz Szozda   schedule 28.12.2015