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

Índice único de varias columnas de Postgres para la tabla de unión

Como clave principal

Haga esto si ese único es la clave principal:

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

No es clave principal

Haga esto si esa clave única no es principal:

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

Tabla existente

Si tiene una tabla existente, haga esto en su lugar:

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

Esa tabla alterada muestra este mensaje:

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


Query returned successfully with no result in 22 ms.

Soltar

Si quisiera eliminar esa restricción (es posible que desee hacer una combinación única de 3 campos):

ALTER TABLE tbl DROP CONSTRAINT tbl_unique;

Índice, Restricción y Nulos

Con respecto al índice, del documento de Postgres:

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

Si la unicidad depende de algunas reglas, debe usar CREATE UNIQUE INDEX , por ejemplo:

Dado esto:

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

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

Ese único puede capturar estos duplicados, esto será rechazado por la base de datos:

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

Sin embargo, esa RESTRICCIÓN ÚNICA no puede detectar nulos duplicados. Los nulos sirven como desconocidos, sirven como comodines, es por eso que se permite tener múltiples nulos en una restricción única. Esto será aceptado por la base de datos:

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

Piense en UNIQUE CONSTRAINT que permite la unicidad diferida, de ahí la aceptación de los valores nulos anteriores.

Si solo desea un comodín (b_id nulo) por a_id, además de la restricción única, debe agregar un UNIQUE INDEX . RESTRICCIÓN ÚNICA no puede tener una expresión en ellos. INDEX y UNIQUE INDEX pueden. Este será su DDL completo para rechazar múltiples nulos;

Este será su 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;      

Esto será rechazado por su base de datos ahora:

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

Esto estará permitido:

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

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