sql >> Base de Datos >  >> RDS >> PostgreSQL

Cree un índice de varias columnas para hacer cumplir la unicidad

Esto parece ser un malentendido.

Su cita de mi respuesta es un poco engañosa, ya que solo se aplica si también crea el índice parcial adicional como se describe allí:
Cómo agregar un índice único condicional en PostgreSQL

Si no agregas este segundo índice (como no lo hiciste), ya tienes tu solución , parecería. Solo con el índice único de varias columnas, puede ingresar (1, NULL) varias veces, pero (1,2) o (1,3) solo una vez.

Cadenas vacías

Si, por error, estaba considerando cadenas vacías ('' ) (para un tipo de carácter ) en lugar de NULL valores:estos se manejan como cualquier otro valor. podrías lidiar con esta situación utilizando un índice único de varias columnas, parcialmente funcional (índice en una expresión ):

CREATE UNIQUE INDEX predictions _dim_tat_uni_idx
ON predictions (tat, NULLIF(dim, ''));

De esta manera puede ingresar (1, 'a') , (1, 'b') solo una vez.
Pero (1, NULL) y (1, '') varias veces.

Efectos secundarios

El índice seguiría siendo totalmente compatible con consultas simples en la primera columna (tat ).
Pero las consultas en ambas columnas tendrían que coincidir con la expresión para utilizar todo el potencial. Esto sería más rápido, incluso si no parece tener sentido:

SELECT * FROM predictions
WHERE  tat = 1
AND    NULLIF(dim, '') = 'foo';

.. que esto:

SELECT * FROM predictions
WHERE  tat = 1
AND    dim = 'foo';

.. porque la primera consulta puede usar ambas columnas de índice. El resultado sería el mismo (excepto al buscar '' o NULL ). Detalles en esta respuesta relacionada en dba.SE .