PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Indice univoco a più colonne di Postgres per la tabella di join

Come chiave primaria

Fallo se quella univoca è la chiave primaria:

create table tbl(
   a_id int not null,
   b_id int not null,
   constraint tbl_pkey primary key(a_id,b_id)
);

Chiave non primaria

Fallo se quella chiave univoca non è primaria:

create table tbl(

   -- other primary key here, e.g.:
   -- id serial primary key,

   a_id int not null,
   b_id int not null,
   constraint tbl_unique unique(a_id,b_id)
);

Tabella esistente

Se hai una tabella esistente, fallo invece:

alter table tbl
      add constraint tbl_unique unique(a_id, b_id)

Quell'alter table mostra questo messaggio:

NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index "tbl_unique" for table "tbl"


Query returned successfully with no result in 22 ms.

Lascia

Se volessi eliminare quel vincolo (potresti voler rendere unica una combinazione di 3 campi):

ALTER TABLE tbl DROP CONSTRAINT tbl_unique;

Indice e Vincolo e Null

Per quanto riguarda l'indice, da Postgres doc:

Fonte:http://www.postgresql.org/docs/9.1 /static/indexes-unique.html

Se l'unicità dipende da alcune regole, devi utilizzare CREATE UNIQUE INDEX , ad esempio:

Detto questo:

CREATE TABLE tbl
(
  a_id integer NOT NULL,
  b_id integer NULL  
);

alter table tbl
    add constraint tbl_unique unique(a_id, b_id);

Quell'unico può catturare questi duplicati, questo verrà rifiutato dal database:

insert into tbl values
(1,1),
(1,1);

Eppure quel CONSTRAINT UNICO non può catturare null duplicati. I valori nulli fungono da sconosciuti, fungono da caratteri jolly, ecco perché è consentito avere più valori nulli in un vincolo univoco. Questo sarà accettato dal database:

insert into tbl values
(1,1),
(1,null), -- think of this null as wildcard, some real value can be assigned later.
(1,null); -- and so is this. that's why both of these nulls are allowed

Pensa a UNIQUE CONSTRAINT che consente l'unicità differita, quindi l'accettazione di valori nulli sopra.

Se desideri un solo carattere jolly (null b_id) per a_id, a parte il vincolo univoco, devi aggiungere un UNIQUE INDEX . UNIQUE CONSTRAINT non può avere un'espressione su di essi. INDEX e UNIQUE INDEX Potere. Questo sarà il tuo DDL completo per aver rifiutato più null;

Questo sarà il tuo DDL completo:

CREATE TABLE tbl
(
  a_id integer NOT NULL,
  b_id integer NULL  
);
alter table tbl
    add constraint tbl_unique unique(a_id, b_id);

create unique index tbl_unique_a_id on tbl(a_id) where b_id is null;      

Questo verrà rifiutato dal tuo database ora:

insert into tbl values
(1,1),
(1,null),
(1,null);

Questo sarà consentito:

insert into tbl values
(1,1),
(1,null);

Relativo a http://www.ienablemuch .com/2010/12/postgresql-said-sql-server2008-said-non.html