2012-01-18 17 views
6

Ho una tabella con line_items seguenti colonne:Come aggiungere un indice univoco subordinata PostgreSQL

product_id 
variant_id 

variant_id è annullabile.

Qui è la condizione:

  • Se variant_id è NULL allora product_id deve essere univoco.
  • Se variant_id ha un valore, la combinazione di product_id e variant_id deve essere univoca.

È possibile in PostgreSQL?

risposta

20

Creare un UNIQUE multicolumn INDEX su (product_id, variant_id):

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

Tuttavia, questo consentirebbe più voci di (1, NULL) per (product_id, variant_id) perchè NULL valori non sono considerate identiche.
per compensare che, in aggiunta a creare un partial UNIQUE INDEX su product_id:

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

In questo modo è possibile inserire (1,2), (1,3) e (1, NULL), ma nessuno dei due per la seconda volta. Accelera anche le query con condizioni su una o entrambe le colonne.

Questo answer on dba.SE di recente ho scritto è molto simile e quasi direttamente applicabile al tuo problema.

0

Un'altra opzione è utilizzare le espressioni nei campi chiave. Questo potrebbe non essere stato intorno quando hai posto la domanda, ma potrebbe essere utile per gli altri che si imbattono in questo ora.

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

Certo, questo presuppone che il variant_id è un intero incremento automatico che ha cominciato a 1. Da notare anche le parentesi intorno all'espressione. Per i documenti, sono obbligatori.

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

Problemi correlati