sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres unika begränsning vs index

Jag hade vissa tvivel om denna grundläggande men viktiga fråga, så jag bestämde mig för att lära mig genom exempel.

Låt oss skapa testtabellen master med två kolumner, con_id med unik begränsning och ind_id indexeras med unikt index.

create table master (
    con_id integer unique,
    ind_id integer
);
create unique index master_unique_idx on master (ind_id);

    Table "public.master"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Indexes:
    "master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
    "master_unique_idx" UNIQUE, btree (ind_id)

I tabellbeskrivningen (\d i psql) kan du skilja unika begränsningar från unika index.

Unikhet

Låt oss kontrollera unika, för säkerhets skull.

test=# insert into master values (0, 0);
INSERT 0 1
test=# insert into master values (0, 1);
ERROR:  duplicate key value violates unique constraint "master_con_id_key"
DETAIL:  Key (con_id)=(0) already exists.
test=# insert into master values (1, 0);
ERROR:  duplicate key value violates unique constraint "master_unique_idx"
DETAIL:  Key (ind_id)=(0) already exists.
test=#

Det fungerar som förväntat!

Främmande nycklar

Nu ska vi definiera detalj tabell med två främmande nycklar som hänvisar till våra två kolumner i master .

create table detail (
    con_id integer,
    ind_id integer,
    constraint detail_fk1 foreign key (con_id) references master(con_id),
    constraint detail_fk2 foreign key (ind_id) references master(ind_id)
);

    Table "public.detail"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Foreign-key constraints:
    "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
    "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)

Tja, inga fel. Låt oss se till att det fungerar.

test=# insert into detail values (0, 0);
INSERT 0 1
test=# insert into detail values (1, 0);
ERROR:  insert or update on table "detail" violates foreign key constraint "detail_fk1"
DETAIL:  Key (con_id)=(1) is not present in table "master".
test=# insert into detail values (0, 1);
ERROR:  insert or update on table "detail" violates foreign key constraint "detail_fk2"
DETAIL:  Key (ind_id)=(1) is not present in table "master".
test=#

Båda kolumnerna kan refereras i främmande nycklar.

Begränsning med index

Du kan lägga till tabellbegränsningar med hjälp av befintligt unikt index.

alter table master add constraint master_ind_id_key unique using index master_unique_idx;

    Table "public.master"
 Column |  Type   | Modifiers
--------+---------+-----------
 con_id | integer |
 ind_id | integer |
Indexes:
    "master_con_id_key" UNIQUE CONSTRAINT, btree (con_id)
    "master_ind_id_key" UNIQUE CONSTRAINT, btree (ind_id)
Referenced by:
    TABLE "detail" CONSTRAINT "detail_fk1" FOREIGN KEY (con_id) REFERENCES master(con_id)
    TABLE "detail" CONSTRAINT "detail_fk2" FOREIGN KEY (ind_id) REFERENCES master(ind_id)

Nu finns det ingen skillnad mellan beskrivning av kolumnbegränsningar.

Delvisa index

I tabellbegränsningsdeklaration kan du inte skapa partiella index. Det kommer direkt från definitionen av create table ... .I unik indexdeklaration kan du ställa in WHERE clause för att skapa partiellt index. Du kan också skapa index på uttryck (inte bara på kolumn) och definiera några andra parametrar (sortering, sorteringsordning, NULLs placering).

Du kan inte lägg till tabellbegränsning med partiellt index.

alter table master add column part_id integer;
create unique index master_partial_idx on master (part_id) where part_id is not null;

alter table master add constraint master_part_id_key unique using index master_partial_idx;
ERROR:  "master_partial_idx" is a partial index
LINE 1: alter table master add constraint master_part_id_key unique ...
                               ^
DETAIL:  Cannot create a primary key or unique constraint using such an index.


  1. Hur kan jag hitta vilka tabeller som refererar till en given tabell i Oracle SQL Developer?

  2. Bästa DBaaS-lösningar för PostgreSQL

  3. Hur man returnerar en lista över språk som stöds i Oracle

  4. Oracle-markör för tilldelning