PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Index multi-colonnes unique Postgres pour la table de jointure

Comme clé primaire

Faites ceci si cet unique est la clé primaire :

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

Pas de clé primaire

Faites ceci si cette clé unique n'est pas une clé primaire :

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)
);

Tableau existant

Si vous avez une table existante, faites ceci à la place :

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

Cet alter table affiche ce message :

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


Query returned successfully with no result in 22 ms.

Laisser tomber

Si vous vouliez supprimer cette contrainte (vous voudrez peut-être rendre unique une combinaison de 3 champs) :

ALTER TABLE tbl DROP CONSTRAINT tbl_unique;

Index &Contrainte &Nulls

Concernant l'index, à partir de la doc Postgres :

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

Si l'unicité dépend de certaines règles, vous devez utiliser CREATE UNIQUE INDEX , par exemple :

Étant donné ceci :

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

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

Cet unique peut attraper ces doublons, cela sera rejeté par la base de données :

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

Pourtant, cette CONTRAINTE UNIQUE ne peut pas attraper les nulls en double. Les valeurs nulles servent d'inconnu, elles servent de caractère générique, c'est pourquoi il est permis d'avoir plusieurs valeurs nulles dans une contrainte unique. Ceci sera accepté par la base de données :

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

Pensez à UNIQUE CONSTRAINT qu'il permet l'unicité différée, d'où l'acceptation des valeurs nulles ci-dessus.

Si vous ne voulez qu'un seul caractère générique (null b_id) par a_id, en dehors de la contrainte unique, vous devez ajouter un UNIQUE INDEX . UNIQUE CONSTRAINT ne peut pas avoir d'expression sur eux. INDEX et UNIQUE INDEX boîte. Ce sera votre DDL complet pour rejeter plusieurs null ;

Ce sera votre DDL complet :

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;      

Cela sera rejeté par votre base de données maintenant :

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

Cela sera autorisé :

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

Lié à http://www.ienablemuch .com/2010/12/postgresql-said-sql-server2008-said-non.html