我對這個基本而重要的問題有些懷疑,所以我決定以身作則。
讓我們來創建測試表主有兩列,CON_ID具有獨特的約束和ind_id通過唯一索引收錄。
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)
在表格描述(psql中的\ d)中,您可以從唯一索引中指出唯一約束。
唯一
讓我們檢查的獨特性,以防萬一。
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=#
它按預期工作!
外鍵
現在,我們將定義詳細表有兩個外鍵引用到我們的兩列主。
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)
好吧,沒有錯誤。讓我們確保它的工作。
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=#
這兩列都可以在外鍵中引用。
約束採用指數
您可以使用現有的唯一索引添加表約束。
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)
現在列約束描述之間沒有區別。
部分索引
在表約束聲明不能創建部分索引。 它直接來自create table ...
的definition。 在唯一索引聲明中,您可以設置WHERE clause
來創建部分索引。 你也可以用create index表達式(不僅在列上)定義一些其他參數(排序規則,排序規則,NULLs佈局)。
您不能使用部分索引添加表約束。使用UNIQUE INDEX
與UNIQUE CONSTRAINT
的
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.
的(唯一的)實際區別是,你可以創建一個外鍵,唯一約束,但不是唯一的指標。 –
其他方式的一個優點([最近在另一個問題中提出]](http://stackoverflow.com/a/23449309/157957))是你可以有一個* partial *唯一索引,比如「Unique( foo)哪裏酒吧是空的「。 AFAIK,沒有辦法做到這一點的約束。 – IMSoP
[Here](http://flatiron.engineering/technology/2016/09/13/uniqueness-in-postgres.html)關於差異的好文章 –