PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Batasan unik Postgres vs indeks

Saya memiliki beberapa keraguan tentang masalah dasar tetapi penting ini, jadi saya memutuskan untuk belajar melalui contoh.

Mari kita buat tabel pengujian master dengan dua kolom, con_id dengan batasan unik dan ind_id diindeks oleh indeks unik.

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)

Dalam deskripsi tabel (\d dalam psql) Anda dapat membedakan batasan unik dari indeks unik.

Keunikan

Yuk cek keunikannya, untuk jaga-jaga.

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

Ini berfungsi seperti yang diharapkan!

Kunci asing

Sekarang kita akan mendefinisikan detail tabel dengan dua kunci asing yang merujuk ke dua kolom kami di 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)

Yah, tidak ada kesalahan. Mari kita pastikan itu berhasil.

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

Kedua kolom dapat direferensikan dalam kunci asing.

Batasan menggunakan indeks

Anda dapat menambahkan batasan tabel menggunakan indeks unik yang ada.

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)

Sekarang tidak ada perbedaan antara deskripsi batasan kolom.

Indeks sebagian

Dalam deklarasi batasan tabel, Anda tidak dapat membuat indeks parsial. Ini berasal langsung dari definisi create table ... .Dalam deklarasi indeks unik Anda dapat mengatur WHERE clause untuk membuat indeks parsial. Anda juga dapat membuat indeks pada ekspresi (tidak hanya pada kolom) dan menentukan beberapa parameter lain (penyusunan, urutan pengurutan, penempatan NULL).

Anda tidak bisa tambahkan batasan tabel menggunakan indeks parsial.

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. PostgreSQL GROUP_CONCAT() Setara

  2. Indeks untuk menemukan elemen dalam array JSON

  3. Bagaimana Anda menambahkan Driver PostgreSQL sebagai ketergantungan di Maven?

  4. Lembar Cheat Kinerja untuk PostgreSQL

  5. Kembalinya XFS di Linux