Харесва ми @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
трябва да бъде зададено NOT NULL
в този случай.
- Как да добавите условен уникален индекс на PostgreSQL
- Създаване на уникално ограничение с нулеви колони
Защо индекс, а не ограничение?
Адресиране на вашия въпрос в коментар
:Това е индекс, а не CONSTRAINT
.
Индексът за първия случай е малък , съдържащ един или нито един ред.
Индексът за втория случай съдържа един ред за съществуващ userid
, но това е най-най-евтиният и най-бързият начин , освен че са чисти и безопасни. Във всеки случай ще ви трябва индекс за проверка на други редове, за да направите това бързо.
Не можете да имате CHECK
проверка на ограничения на други редове - поне не по чист и надежден начин. Има начини, които със сигурност не бих препоръчал за този случай:
- Ограничение за задействане срещу проверка
- Как да избегнем циклична зависимост (кръгова препратка) между 3 таблици?
- Деактивирайте всички ограничения и проверки на таблици, докато възстановявате дъмп
Ако използвате UNIQUE
ограничение върху (userid, status)
(което също е имплементирано с уникален индекс във фонов режим!), не можете да го направите частично и всички комбинациите се налагат да бъдат уникални. Вие можете все още използвайте това, ако работите с status IS NULL
за всички случаи с изключение на 'Active'
случай. Но това всъщност би наложило много по-голям индекс, включително всички редове.