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

Crear restricción única con columnas nulas

Crear dos índices parciales :

CREATE UNIQUE INDEX favo_3col_uni_idx ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;

CREATE UNIQUE INDEX favo_2col_uni_idx ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;

De esta forma, solo puede haber una combinación de (user_id, recipe_id) donde menu_id IS NULL , implementando efectivamente la restricción deseada.

Posibles inconvenientes:

  • No puede tener una clave externa que haga referencia a (user_id, menu_id, recipe_id) . (Parece poco probable que desee una referencia FK de tres columnas de ancho; ¡utilice la columna PK en su lugar!)
  • No puedes basar CLUSTER en un índice parcial.
  • Consultas sin un WHERE coincidente la condición no puede usar el índice parcial.

Si necesita un completo index, alternativamente puede colocar el WHERE condición de favo_3col_uni_idx y sus requisitos aún se aplican.
El índice, que ahora comprende toda la tabla, se superpone con el otro y se hace más grande. Según las consultas típicas y el porcentaje de NULL valores, esto puede o no ser útil. En situaciones extremas, incluso puede ayudar mantener los tres índices (los dos parciales y un total en la parte superior).

Esta es una buena solución para una única columna anulable , tal vez para dos. Pero se sale de las manos rápidamente para obtener más, ya que necesita un índice parcial separado para cada combinación de columnas anulables, por lo que el número crece binomialmente. Para varias columnas anulables , véase en su lugar:

  • ¿Por qué no se activa mi restricción ÚNICA?

Aparte:aconsejo no usar identificadores de mayúsculas y minúsculas en PostgreSQL.