外鍵的一些注意事項

  • 2019 年 11 月 6 日
  • 筆記

外鍵的一些注意事項

昨天的文章中,重溫了一下外鍵的使用方式,今天再聊聊外鍵的一些其他注意事項。

首先需要了解的是,InnoDB是目前唯一支持外鍵的內置存儲引擎。使用外鍵是有一定成本的。這裡討論一下外鍵的優劣勢:

優勢:

使用外鍵在某些場景下能夠提升一些性能,比如我們想確保兩個相關表始終具有一致的數據,那麼使用外鍵的方法要比直接查詢兩張表數據是否一致性能高得多,除了這個之外,外鍵在相關數據的刪除和更新上,也比在應用程序中維護更加高效。不過這裡需要注意的是,外鍵的維護操作是逐行記錄進行的,所以這種更新會比批量刪除和更新的速度慢一些。

劣勢:

外鍵通常都要求每次在修改數據時在另外一張表中執行一次查找操作,雖然在innodb中強制外鍵使用索引,但是還是會帶來額外開銷,在一些基數比較小的索引上創建外鍵,還有可能嚴重影響性能。除此之外,外鍵約束使得查詢需要額外訪問一些別的表,以為著會需要額外的鎖開銷,例如,我們在子表中插入一條記錄,外鍵約束會讓innodb檢查父表對應的記錄,也就需要對父表加鎖從而確保這條記錄不會在該事務完成之前被刪除掉。這個操作會導致額外的所等待,還有可能出現死鎖的現象。

基於這種劣勢,所以我們在包含外鍵的表中,如果需要導入數據,則會通過暫時關閉外鍵的方法來保證導入數據的時候,不進行外鍵檢查,從而提高插入的性能,如下:

第一步、set foreign_key_checks = 0;

第二步、load data …

第三步、set foreign_key_checks = 1;

在實際的生產環境中,一般還是建議讓數據庫去做它最擅長的事兒,就是單純的數據存儲和數據查詢。外鍵約束、存儲過程、觸發器、函數這些包含處理邏輯的功能,還是盡量不要使用,一旦表裏面的記錄量級上來了,那麼這些功能很容易成為關係型數據庫的瓶頸。