Tôi đã có một số nghi ngờ về vấn đề cơ bản nhưng quan trọng này, vì vậy tôi quyết định tìm hiểu bằng ví dụ.
Hãy tạo chủ bảng thử nghiệm với hai cột, con_id với ràng buộc duy nhất và ind_id được lập chỉ mục bởi chỉ mục duy nhất.
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)
Trong mô tả bảng (\ d trong psql), bạn có thể cho biết ràng buộc duy nhất từ chỉ mục duy nhất.
Độc đáo
Hãy kiểm tra tính độc đáo, chỉ trong trường hợp.
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=#
Nó hoạt động như mong đợi!
Khóa ngoại
Bây giờ chúng ta sẽ xác định chi tiết bảng với hai phím nước ngoài tham chiếu đến hai cột của chúng tôi trong tổng thể .
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)
Vâng, không có lỗi. Hãy chắc chắn rằng nó hoạt động.
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=#
Cả hai cột có thể được tham chiếu trong khóa ngoại.
Hạn chế sử dụng chỉ mục
Bạn có thể thêm ràng buộc bảng bằng chỉ mục duy nhất hiện có.
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)
Bây giờ không có sự khác biệt giữa mô tả ràng buộc cột.
Chỉ số một phần
Trong khai báo ràng buộc bảng, bạn không thể tạo các chỉ mục một phần. Nó đến trực tiếp từ định nghĩa của create table ...
. Trong khai báo chỉ mục duy nhất, bạn có thể thiết lập WHERE clause
để tạo chỉ mục một phần. Bạn cũng có thể tạo chỉ mục trên biểu thức (không chỉ trên cột) và xác định một số tham số khác (đối chiếu, thứ tự sắp xếp, vị trí NULL).
Bạn không thể thêm ràng buộc bảng bằng chỉ mục một phần.
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.