爲何大多數互聯網公司不用外鍵約束

是否使用外鍵約束

【強制】不得使用外鍵與級聯,一切外鍵概念必須在應用層解決.-《阿里Java規範》html

首先外鍵(Foreign Key)是什麼東西

使用方案

假設有一個score表 id是自增id,score是分數,student_id是學號。sql

另外一個student表,id是自增id,name是名字,student_id是學號。數據庫

那麼設計這個的時候就但願有一個關聯關係,讓score的student_id指向student表的student_id,存在一個學生對應多個成績的關係。因此我可使用如下SQL語句服務器

ALTER TABLE score
ADD CONSTRAINT FOREIGN KEY (student_id)
REFERENCES student(student_id);

建立一個外鍵索引完成這個規則併發

完成後的表關係以下框架

外鍵原理

被指向的字段,具備惟一性高併發

能夠保證成績字段的一致性,即每一次插入一個score數據,首先要檢測是否student表存在這個id,保證一致性性能

若是在外鍵類型上使用CASCADE,則會保證在作更新和刪除sutudent表的student_id時,觸發一次級聯操做,會同步更新score表的student_id或者刪除student_id.設計

外鍵類型RESTRICT 也一樣會作一次檢測,但不會作級聯操做,而是直接拒絕操做。
3d

場景思考

知道外鍵是什麼後,咱們來思考一個場景:

如今有一個電商系統,用戶有一個帳戶id,商品有一個商品id,這兩個字段和訂單綁定,此時訂單id和帳戶表ID構成一個外鍵關係,同時和商品表id也構成一個外鍵關係,那麼我每次生成一筆訂單,就須要向另外兩張表查詢檢測一次數據,那麼就存在幾個問題:

  • 增刪改觸發這個查詢操做的性能消耗,服務器系統是否容許
  • 在其餘表查詢會上須要對其餘表作一個內部鎖,是否存在高併發死鎖狀況
  • 數據一致性所有交給數據庫服務器,數據庫服務器是否可以承受

這些問題在互聯網公司會顯得格外嚴重,由於訪問流量大的時候以上問題基本上是徹底沒法獲得MySQL系統自己解決的

同時在作分庫分表設計的時候,外鍵約束就會顯得格外離譜。

同時MySQL系統的外鍵設計是背離部分SQL標準的

引用自博客園Eden: (https://www.cnblogs.com/discuss/articles/1862244.html)

對SQL標準的背離:若是ON UPDATE CASCADE或ON UPDATE SET NULL遞歸更新相同的表,以前在級聯過程當中該表一被更新過,它就象RESTRICT同樣動做。這意味着你不能使用自引用ON UPDATE CASCADE或者ON UPDATE SET NULL操做。這將阻止級聯更新致使的無限循環。另外一方面,一個自引用的ON DELETE SET NULL是有可能的,就像一個自引用ON DELETE CASCADE同樣。級聯操做不能夠被嵌套超過15層深。

對SQL標準的背離: 相似通常的MySQL,在一個插入,刪除或更新許多行的SQL語句內,InnoDB逐行檢查UNIQUE和FOREIGN KEY約束。按照SQL的標準,默認的行爲應被延遲檢查,即約束僅在整個SQL語句被處理以後才被檢查。直到InnoDB實現延遲的約束檢查以前,一些事情是不可能的,好比刪除一個經過外鍵參考到自身的記錄。

處理

由於以上問題,咱們一般在建模時隱性設計外鍵約束,實際實現採用業務邏輯模擬外鍵的方式處理,這樣能夠解決把一致性所有放在DBA上的性能問題,同時咱們能夠採用容許髒數據存在,而後定時數據清理的方案去保證數據處理的分時性能,避免高峯處理。

這樣的好處:

  • 解決性能問題
  • 增長了可擴展性,框架遷移不用在數據庫系統內部實現邏輯約束
  • 分庫分表的時候方便
  • 不會在DB層面形成死鎖

反推:是否可使用外鍵約束

我以爲在部分業務場景下是能夠考慮使用的,回到最開始的例子,教務系統的成績模塊重要的點再也不是性能問題,而是高可靠,由於對學校來講,系統存在如下特色:

  • 數據量較少,一個學校學生最多不超過10萬人,一般在5000-50000這個區間內,對DB來講這是一個很小的數據量
  • 數據不允許出錯,由於成績和學生的人身利益直接掛鉤
  • 可以進行數據修改操做的用戶極少,只有教務處錄入成績的老師。
  • 若是放在業務部分,若是出現student表student_id在第一次被刪除後,未清理score表數據,這個student_id短期內被再次使用,而沒有作數據清理,就容易出現成績複用錯誤,諸如此類

因此 不得使用外鍵與級聯,一切外鍵概念必須在應用層解決。 大部分狀況下正確,但一樣我認爲須要分業務場景解決,並不能一竿子打死。

相關文章
相關標籤/搜索