Mysql

唯一約束替換現有外鍵

  • March 31, 2022

我有兩個表,parent並且child該表在使用該列的child表上有一個 FK 。添加此 FK 時,我可以看到該表同時具有 FK 和表示該 FK 的索引。parent``parent_id``child

child但是當我在包含的表上添加一個唯一約束時,parent_id我可以看到代表 FK 的索引被替換為新的唯一約束。

前任:

create table parent
(
   parent_id int unsigned not null auto_increment primary key
);
create table child
(
   child_id int unsigned not null auto_increment primary key,
   parent_id int unsigned not null,
   age smallint unsigned null,
   constraint FK__CHILD__PARENT
       foreign key (parent_id) references parent (parent_id)
);

此時我可以看到表上同時FK_CHILD_PARENT存在一個 FK 和一個名為的索引child

現在我添加唯一約束:

alter table child add constraint unique_parentId_age unique (parent_id, age);

我可以看到unique_parentId_age索引替換了FK__CHILD__PARENT索引。

我不明白為什麼會這樣?如果另一個索引已經存在並且以與 FK 相同的列開頭,是否不可能有一個表示 FK 的索引。

我正在使用 MySQL 5.7

如果另一個索引已經存在並且以與 FK 相同的列開頭,是否不可能有一個表示 FK 的索引。

索引不代表鍵約束;它獨立於約束而存在並支持其執行。擁有冗餘索引在技術上是可能的,但它是不必要的:任何受益於索引 on 的查詢(parent_id)都可以同樣好地由索引 on 支持(parent_id, age),並且維護冗餘索引不利於性能。

這是按設計和記錄工作的(強調我的):

在引用表中,必須有一個索引,其中外鍵列按相同順序列為第一列。如果引用表不存在,則會在引用表上自動創建此類索引。如果您創建另一個可用於強制外鍵約束的索引,此索引可能會在稍後被靜默刪除

如果出於某種原因您堅持使用冗餘索引,我想您可以嘗試顯式創建它並給它一個非預設名稱。

引用自:https://dba.stackexchange.com/questions/310406