Me gusta /a> , status
realmente debería ser boolean
. Más barato, más limpio.
De cualquier manera, puede imponer su regla con un índice único parcial :
Para permitir cero o una fila con status = 'Active'
en toda la tabla :
CREATE UNIQUE INDEX tbl_active_uni ON tbl (status)
WHERE status = 'Active';
Para permitir cero o una fila con status = 'Active'
por userid
, crea userid
la columna indexada:
CREATE UNIQUE INDEX tbl_userid_active_uni ON tbl (userid)
WHERE status = 'Active';
Tenga en cuenta que userid IS NULL
no desencadenaría infracciones únicas, porque dos valores NULL nunca se consideran iguales. userid
debe ser establecer NOT NULL
en este caso.
- Cómo agregar un índice único condicional en PostgreSQL
- Crea una restricción única con columnas nulas
¿Por qué indexar y no restringir?
Abordar su pregunta en el comentario
:Este es un índice, no un CONSTRAINT
.
El índice para el primer caso es pequeño , con una o ninguna fila.
El índice para el segundo caso contiene una fila por userid
existente , pero es la forma más barata y rápida , además de ser limpio y seguro. Necesitaría un índice para verificar otras filas en cualquier caso para hacer esto rápido.
No puede tener un CHECK
verificación de restricciones en otras filas, al menos no de una manera limpia y confiable. Hay formas que ciertamente no recomendaría para este caso:
- Restricción de activación frente a verificación
- ¿Cómo evitar una dependencia cíclica (referencia circular) entre 3 tablas?
- Deshabilitar todas las restricciones y comprobaciones de tablas al restaurar un volcado
Si usa un UNIQUE
restricción en (userid, status)
(¡que también se implementa con un índice único en segundo plano!), no puede hacerlo parcial y todos las combinaciones se imponen para ser únicas. podrías Todavía use esto si trabaja con status IS NULL
para todos los casos excepto el 'Active'
caso. Pero eso en realidad impondría un índice mucho más grande que incluiría a todos filas.