Mysql關於數據庫是否應該使用外鍵約束詳解說明

一、前言

對於【是否使用外鍵約束】這個話題已經是老生常談的瞭。在學校中,老師交給我們的大多是需要我們建立外鍵約束,但進入瞭實際工作很多時候並不會使用外鍵,而是通過代碼邏輯來控制。包括在阿裡的JAVA規范中也明確規定:【強制】不得使用外鍵與級聯,一切外鍵概念必須在應用層解決。

為什麼要做這樣的規定呢?到底該不該使用外鍵約束呢?我們可以舉一個例子來說明

二、舉例說明

現在我們在數據庫中建立瞭兩張表:【product和project】,【project】的porduct字段,關聯Product,他們之間存在下圖這樣的一條外鍵記錄:

在這裡插入圖片描述

當我們對【project】表增加一條project_id為 1 的記錄的時候,由於【product】表不存在相應的記錄會導致報錯:

在這裡插入圖片描述

可以看出,這個約束的存在,會保證表間數據的關系的完整性。更不容易出現臟數據。這是外鍵約束非常明顯的優點!

總結一下,外鍵約束具有如下的優點:

  • 保證數據的完整性和一致性
  • 級聯操作方便
  • 將數據完整性判斷托付給瞭數據庫完成,減少瞭程序的代碼量

但也存在著不可忽略的缺點:

性能問題

我們剛建立瞭兩張表【project】和【product】,【project】表通過project_id字段與【product】表做瞭外鍵約束。

這個時候,當我們每次往【project】表插入數據的時候,它會先去【product】中查詢是否有對應的關聯數據,如果通過程序來控制可以不進行這次查詢。但設立瞭外鍵約束,就一定會去進行該查詢。這實際是冗餘的。當關聯的字段少的時候可能沒啥影響,但一但關聯字段多瞭後,這種影響就尤其明顯!

死鎖

外鍵導致查詢需要依賴其他數據表,這意味著 InnoDB 需要在父級表(或相關表)中檢驗相應的值。這也會鎖定父級表的數據行,以保證在事務完成前該行不會被刪除。這會導致意外的鎖等待,甚至是死鎖,這類問題很難被定位。

分庫分表困難

加瞭約束的數據庫在需要分庫分表的情況下,會特別困難

開發/測試效率的降低

在我們日常的測試過程中,經常會遇到發現瞭一個BUG想復現或者方便測試的情況,會直接改數據庫表的數據來達到方便測試的效果。

雖然這及不規范,但實際情況就是能夠提升我們很多效率。這是毋庸置疑的!可是,這樣的操作也會帶來一些問題,比如因為數據導致的BUG,但實際並不是程序的BUG,或者發現不瞭一些潛在的BUG。

三、總結

目前很多互聯網公司,特別是大廠對於外鍵的態度都是要求禁用。這其實不單單因為性能問題,主要也因為互聯網的業務變化快,會間接導致表結構容易發生變動,很可能會因為外鍵約束的存在導致導意想不到的問題和開發效率的降低。因此,在非必要的情況、不需要高可靠性的業務場景下,不建議使用外鍵約束,這樣更能夠擁抱變化。
但我們並不能一桿子打死,因為有的業務場景反而使用外鍵約束更好,比如政務、銀行、軍工等需要數據高可靠的情況下。所以我的建議是:如果是業務相對復雜的話,可以在測試環境使用外鍵約束,但上瞭生產環境需要去掉。如果業務相對簡單,那完全可以刪除外鍵約束。但對於銀行、軍工行業這些不允許數據出錯,需要高可靠性的場景下,還是建議建立外鍵約束。

到此這篇關於Mysql關於數據庫是否應該使用外鍵約束詳解說明的文章就介紹到這瞭,更多相關Mysql 數據庫外鍵約束內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: