2014-10-21 2 views
1

Вот проблема, с которой я сталкиваюсь с уникальными ограничениями: допустим, у меня есть таблица app_user. И у него есть столбец «имя», а столбец «is_active». Поэтому, если «is_active» является ложным, пользователь удаляется.postgresql - уникальный с ограничением на извлечение

Теперь я хочу уникальное ограничение на столбец «имя». Затем пользователь удаляется, а затем кто-то хочет добавить снова пользователя с тем же именем, он терпит неудачу из-за уникального ограничения. Я мог бы поместить эту проверку в верхние слои (и для действий, вызванных пользователем, которые на самом деле не происходят, что часто, вероятно, достаточно безопасно, хотя это дополнительный код).

Но я бы хотел установить уникальное ограничение PostgreSQL, которое будет работать только в строках, где is_active = true.

Я просмотрел функцию PostgreSQL 9 EXCLUDES.

я придумал что-то вроде этого:

alter table test add exclude (name with =, is_active with ||) 

Так что идея, так что существует единственный конфликт, я должен иметь оба названия равно, и оба is_active должны быть правдой, тоже. К сожалению, в этом случае оператор || не существует.

В любом случае это может быть достигнуто? Или вы предлагаете другие решения, которые по-прежнему будут уважать требования (возможность воссоздать пользователя с тем же именем, что и удаленный пользователь)? Одним из вариантов было бы сказать, что это невозможно, но предотвращение доступа пользователей к определенному имени пользователя навсегда является немного сильным.

Кроме того, бизнес-логика на самом деле не зависит от не дублирования, но это еще здоровая практика, чтобы предотвратить ее. В этом случае я буду импортировать данные в систему, а импорт - по имени. Поэтому, если у меня есть две записи с тем же именем, у меня будет проблема. Если была запись с таким именем, которая была удалена 6 месяцев назад, и в то же время была создана новая, это не проблема.

И я был бы очень рад, если бы было решение, совместимое с другими SQL-серверами, но я сомневаюсь, что существует ... Кроме того, я бы предпочел не добавлять дополнительные таблицы для достижения этого. Поэтому я думаю, что это либо путь EXCLUDE, либо ничего ...

ответ

3

Вам не требуется ограничение на исключение.

Частичное уникальный индекс достаточно

create unique index unique_active_name 
    on app_user (name) 
    where is_active; 

(это предполагает, что is_active определяется как boolean)

Смежные вопросы