Mysql關于數(shù)據(jù)庫是否應該使用外鍵約束詳解說明
一、
對于【是否使用外鍵約束】這個話題已經(jīng)是老生常談的了。在學校中,老師交給我們的大多是需要我們建立外鍵約束,但進入了實際工作很多時候并不會使用外鍵,而是通過代碼邏輯來控制。包括在阿里的JAVA規(guī)范中也明確規(guī)定:【強制】不得使用外鍵與級聯(lián),一切外鍵概念必須在應用層解決。
為什么要做這樣的規(guī)定呢?到底該不該使用外鍵約束呢?我們可以舉一個例子來說明
二、舉例說明
現(xiàn)在我們在數(shù)據(jù)庫中建立了兩張表:【product和project】,【project】的porduct字段,關聯(lián)Product,他們之間存在下圖這樣的一條外鍵記錄:

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

可以看出,這個約束的存在,會保證表間數(shù)據(jù)的關系的完整性。更不容易出現(xiàn)臟數(shù)據(jù)。這是外鍵約束非常明顯的優(yōu)點!
總結一下,外鍵約束具有如下的優(yōu)點:
- 保證數(shù)據(jù)的完整性和一致性
- 級聯(lián)操作方便
- 將數(shù)據(jù)完整性判斷托付給了數(shù)據(jù)庫完成,減少了程序的代碼量
但也存在著不可忽略的缺點:
性能問題
我們剛建立了兩張表【project】和【product】,【project】表通過project_id字段與【product】表做了外鍵約束。
這個時候,當我們每次往【project】表插入數(shù)據(jù)的時候,它會先去【product】中查詢是否有對應的關聯(lián)數(shù)據(jù),如果通過程序來控制可以不進行這次查詢。但設立了外鍵約束,就一定會去進行該查詢。這實際是冗余的。當關聯(lián)的字段少的時候可能沒啥影響,但一但關聯(lián)字段多了后,這種影響就尤其明顯!
死鎖
外鍵導致查詢需要依賴其他數(shù)據(jù)表,這意味著 InnoDB 需要在父級表(或相關表)中檢驗相應的值。這也會鎖定父級表的數(shù)據(jù)行,以保證在事務完成前該行不會被刪除。這會導致意外的鎖等待,甚至是死鎖,這類問題很難被定位。
分庫分表困難
加了約束的數(shù)據(jù)庫在需要分庫分表的情況下,會特別困難
開發(fā)/測試效率的降低
在我們日常的測試過程中,經(jīng)常會遇到發(fā)現(xiàn)了一個BUG想復現(xiàn)或者方便測試的情況,會直接改數(shù)據(jù)庫表的數(shù)據(jù)來達到方便測試的效果。
雖然這及不規(guī)范,但實際情況就是能夠提升我們很多效率。這是毋庸置疑的!可是,這樣的操作也會帶來一些問題,比如因為數(shù)據(jù)導致的BUG,但實際并不是程序的BUG,或者發(fā)現(xiàn)不了一些潛在的BUG。
三、總結
目前很多互聯(lián)網(wǎng)公司,特別是大廠對于外鍵的態(tài)度都是要求禁用。這其實不單單因為性能問題,主要也因為互聯(lián)網(wǎng)的業(yè)務變化快,會間接導致表結構容易發(fā)生變動,很可能會因為外鍵約束的存在導致導意想不到的問題和開發(fā)效率的降低。因此,在非必要的情況、不需要高可靠性的業(yè)務場景下,不建議使用外鍵約束,這樣更能夠擁抱變化。
但我們并不能一桿子打死,因為有的業(yè)務場景反而使用外鍵約束更好,比如政務、銀行、軍工等需要數(shù)據(jù)高可靠的情況下。所以我的建議是:如果是業(yè)務相對復雜的話,可以在測試環(huán)境使用外鍵約束,但上了生產(chǎn)環(huán)境需要去掉。如果業(yè)務相對簡單,那完全可以刪除外鍵約束。但對于銀行、軍工行業(yè)這些不允許數(shù)據(jù)出錯,需要高可靠性的場景下,還是建議建立外鍵約束。
到此這篇關于Mysql關于數(shù)據(jù)庫是否應該使用外鍵約束詳解說明的文章就介紹到這了,更多相關Mysql 數(shù)據(jù)庫外鍵約束內容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持本站!
版權聲明:本站文章來源標注為YINGSOO的內容版權均為本站所有,歡迎引用、轉載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務器上建立鏡像,否則將依法追究法律責任。本站部分內容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內容涉嫌侵權,請聯(lián)系alex-e#qq.com處理。
關注官方微信