PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Unikatowe ograniczenie Postgresa a indeks

Miałem pewne wątpliwości co do tej podstawowej, ale ważnej kwestii, więc postanowiłem uczyć się na przykładzie.

Stwórzmy tabelę testową master z dwiema kolumnami, con_id z unikalnym ograniczeniem i ind_id indeksowane według unikalnego indeksu.

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)

W opisie tabeli (\d w psql) możesz odróżnić unikalne ograniczenie od unikalnego indeksu.

Wyjątkowość

Sprawdźmy unikalność, na wszelki wypadek.

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=#

Działa zgodnie z oczekiwaniami!

Klucze obce

Teraz zdefiniujemy szczegóły tabela z dwoma kluczami obcymi odnoszącymi się do naszych dwóch kolumn w 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)

Cóż, żadnych błędów. Upewnijmy się, że to działa.

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=#

Do obu kolumn można się odwoływać w kluczach obcych.

Ograniczenie za pomocą indeksu

Możesz dodać ograniczenie tabeli, używając istniejącego unikalnego indeksu.

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)

Teraz nie ma różnicy między opisem ograniczeń kolumn.

Indeksy częściowe

W deklaracji ograniczenia tabeli nie można tworzyć indeksów częściowych. Pochodzi bezpośrednio z definicji create table ... .W unikalnej deklaracji indeksu możesz ustawić WHERE clause aby utworzyć indeks częściowy. Możesz również utworzyć indeks na wyrażeniu (nie tylko na kolumnie) i zdefiniować kilka innych parametrów (sortowanie, porządek sortowania, umieszczanie wartości NULL).

nie możesz dodaj ograniczenie tabeli za pomocą indeksu częściowego.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Skalowanie PostgreSQL dla dużych ilości danych

  2. Numery seryjne na grupę wierszy dla klucza złożonego

  3. Tworzenie częściowego unikalnego indeksu za pomocą sqlalchemy na Postgres

  4. Warunek SQL LIKE do sprawdzenia liczby całkowitej?

  5. PostgreSQL - zapytanie ze skryptu bash jako użytkownik bazy danych 'postgres'