2012-01-18 15 views
6

Tengo una tabla con las siguientes columnas line_items:Cómo agregar un índice único condicionada a PostgreSQL

product_id 
variant_id 

variant_id es anulable.

Aquí es la condición:

  • Si variant_id es NULL entonces product_id debe ser único.
  • Si variant_id tiene un valor, la combinación de product_id y variant_id debe ser única.

¿Eso es posible en PostgreSQL?

Respuesta

20

Crear una UNIQUE multicolumn INDEX en (product_id, variant_id):

CREATE UNIQUE INDEX line_items_prod_id_var_id_idx 
ON line_items (product_id, variant_id); 

Sin embargo, esto permitiría múltiples entradas de (1, NULL) para (product_id, variant_id) PORQUE NULL valores no se consideran idénticos.
para compensar la que, además, crear un partial UNIQUE INDEX en product_id: De esta manera

CREATE UNIQUE INDEX line_items_prod_id_var_null_idx 
ON line_items (product_id) 
WHERE variant_id IS NULL; 

puede introducir (1,2), (1,3) y (1, NULL), pero ninguno de ellos por segunda vez. También acelera consultas con condiciones en una o ambas columnas.

Este answer on dba.SE recientemente escribí es muy similar y casi directamente aplicable a su problema.

0

Otra opción es usar expresiones en los campos clave. Esto puede no haber existido cuando hizo la pregunta, pero podría ser útil para otros que se encuentran con esto ahora.

CREATE UNIQUE INDEX line_items_prod_id_var_id_idx 
ON line_items (product_id, (coalesce(variant_id, 0))); 

Por supuesto, esto supone que su variant_id es un número entero de incremento automático que se inició a 1. También tenga en cuenta los paréntesis alrededor de la expresión. Según los documentos, son obligatorios.

http://www.postgresql.org/docs/9.3/static/sql-createindex.html

Cuestiones relacionadas