[轉帖]數據庫,傻逼才用外鍵約束!

數據庫,傻逼才用外鍵約束!

做者:孤獨煙

來自:打雜的ZRJhtml

引言

其實這個話題是老生常談,不少人在工做中確實也不會使用外鍵。包括在阿里的JAVA規範中也有下面這一條sql

【強制】不得使用外鍵與級聯,一切外鍵概念必須在應用層解決。 數據庫

可是呢,詢問他們緣由,大可能是這麼回答的服務器

每次作DELETE 或者UPDATE都必須考慮外鍵約束,會致使開發的時候很痛苦,測試數據極爲不方便。併發

坦白說,這麼說也是對的。可是呢,不夠全面,因此開一文來詳細說明。框架

正文

首先咱們明確一點,外鍵約束是一種約束,這個約束的存在,會保證表間數據的關係「始終完整」。所以,外鍵約束的存在,並不是全然沒有優勢。
好比使用外鍵,能夠高併發

  • 保證數據的完整性和一致性性能

  • 級聯操做方便測試

  • 將數據完整性判斷託付給了數據庫完成,減小了程序的代碼量code

然而,魚和熊掌不可兼得。外鍵是可以保證數據的完整性,可是會給系統帶來不少缺陷。正是由於這些缺陷,才致使咱們不推薦使用外鍵,具體以下

性能問題

假設一張表名爲user_tb。那麼這張表裏有兩個外鍵字段,指向兩張表。那麼,每次往user_tb表裏插入數據,就必須往兩個外鍵對應的表裏查詢是否有對應數據。若是交由程序控制,這種查詢過程就能夠控制在咱們手裏,能夠省略一些沒必要要的查詢過程。可是若是由數據庫控制,則是必需要去這兩張表裏判斷。

併發問題

在使用外鍵的狀況下,每次修改數據都須要去另一個表檢查數據,須要獲取額外的鎖。如果在高併發大流量事務場景,使用外鍵更容易形成死鎖。

擴展性問題

這裏主要是分爲兩點

  • 作平臺遷移方便,好比你從Mysql遷移到Oracle,像觸發器、外鍵這種東西,均可以利用框架自己的特性來實現,而不用依賴於數據庫自己的特性,作遷移更加方便。

  • 分庫分表方便,在水平拆分和分庫的狀況下,外鍵是沒法生效的。將數據間關係的維護,放入應用程序中,爲未來的分庫分表省去不少的麻煩。

技術問題

使用外鍵,其實將應用程序應該執行的判斷邏輯轉移到了數據庫上。那麼這意味着一點,數據庫的性能開銷變大了,那麼這就對DBA的要求就更高了。不少中小型公司因爲資金問題,並無聘用專業的DBA,所以他們會選擇不用外鍵,下降數據庫的消耗。相反的,若是該約束邏輯在應用程序中,發現應用服務器性能不夠,能夠加機器,作水平擴展。若是是在數據庫服務器上,數據庫服務器會成爲性能瓶頸,作水平擴展比較困難。

相關文章
相關標籤/搜索