MySQL外來鍵約束簡介

2022-09-14 23:27:25 字數 806 閱讀 4532

innodb是目前mysql中唯一支援外來鍵的內建儲存引擎,所以如果需要外來鍵支援那選擇 就不多了(pbxt也有外來鍵支援)。 

使用外來鍵是有成本的。比如外來鍵通常都要求每次在修改資料時都要在另外一張表中多執行一次查詢操作。雖然innodb強制外來鍵使用索引,但還是無法消除這種約束檢查的開銷。如果外來鍵列的選擇性很低,則會導致乙個非常大且選擇性很低的索引。例如,在乙個非常大的表上有status列,並希望限制這個狀態列的取值,如果該列只能取三個值——雖然這個列本身很小,但是如果主鍵很大,那麼這個索引就會很大——而且這個索引除了做這個外來鍵限制,也沒有任何其他的作用了。

不過,在某些場景下,外來鍵會提公升一些效能。如果想確保兩個相關表始終有一致的資料,那麼使用外來鍵比在應用程式中檢查一致性的效能要高得多,此外,外來鍵在相關資料的刪除和更新上,也比在應用中維護要更髙效,不過,外來鍵維護操作是逐行進行的,所以這樣的更新會比批量刪除和更新要慢些。

外來鍵約束使得查詢需要額外訪問一些別的表,這也意味著需要額外的鎖。如果向子表中寫入一條記錄,外來鍵約束會讓innodb檢查對應的父表的記錄,也就需要對父表對應記錄進行加鎖操作,來確保這條記錄不會在這個事務完成之時就被刪除了。這會導致額外的鎖等待,甚至會導致一些死鎖。因為沒有直接訪問這些表,所以這類死鎖問題往往難以排查。

有時,可以使用觸發器來代替外來鍵。對於相關資料的同時更新外來鍵更合適,但是如果外來鍵只是用作數值約束,那麼觸發器或者顯式地限制取值會更好些。(這裡,可以直接使用enum型別。)

如果只是使用外來鍵做約束,那通常在應用程式裡實現該約束會更好。外來鍵會帶來很大的額外消耗。這裡沒有相關的基準測試的資料,不過我們碰到過很多案例,在對效能進行剖析時發現外來鍵約束就是瓶頸所在,刪除外來鍵後效能立即大幅提公升。

mysql約束與外來鍵 MySQL 外來鍵與約束

外來鍵的建立 建表如下 create table parent id int not null,primary key id type innodb create table child id int,parent id int,foreign key parent id references pa...

MySQL 外來鍵約束

建立測試主表.id 是主鍵.create table test main id int,value varchar 10 primary key id 建立測試子表.create table test sub id int,main id int,value varchar 10 primary k...

MySQL外來鍵約束

innodb型別表有乙個其他儲存引擎不支援的特性 外來鍵約束。當b表的外來鍵關聯到a表的主鍵時 表b是父表a表的子表 如果刪除了a表,那麼b中的外來鍵則仍然關聯著乙個不存在的表的主鍵。而外鍵約束則設定了當約束被破壞時應該應用的的規則,包括防止約束破壞。建立乙個外來鍵約束的語法是 foreign ke...