1. 程式人生 > 其它 >MySQL外來鍵約束簡介

MySQL外來鍵約束簡介

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

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

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

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

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

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

作者:小家電維修

相見有時,後會無期。