日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql 外键_为什么大多数互联网公司不用外键约束

發(fā)布時(shí)間:2025/3/15 数据库 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 外键_为什么大多数互联网公司不用外键约束 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

是否使用外鍵約束

【強(qiáng)制】不得使用外鍵與級(jí)聯(lián),一切外鍵概念必須在應(yīng)用層解決.-《阿里Java規(guī)范》

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

使用方案

假設(shè)有一個(gè)score表 id是自增id,score是分?jǐn)?shù),student_id是學(xué)號(hào)。

另一個(gè)student表,id是自增id,name是名字,student_id是學(xué)號(hào)。

那么設(shè)計(jì)這個(gè)的時(shí)候就希望有一個(gè)關(guān)聯(lián)關(guān)系,讓score的student_id指向student表的student_id,存在一個(gè)學(xué)生對(duì)應(yīng)多個(gè)成績(jī)的關(guān)系。所以我可以使用以下SQL語(yǔ)句

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

創(chuàng)建一個(gè)外鍵索引完成這個(gè)規(guī)則

完成后的表關(guān)系如下

外鍵原理

被指向的字段,具有唯一性

可以保證成績(jī)字段的一致性,即每一次插入一個(gè)score數(shù)據(jù),首先要檢測(cè)是否student表存在這個(gè)id,保證一致性

如果在外鍵類型上使用CASCADE,則會(huì)保證在做更新和刪除sutudent表的student_id時(shí),觸發(fā)一次級(jí)聯(lián)操作,會(huì)同步更新score表的student_id或者刪除student_id.

外鍵類型RESTRICT 也同樣會(huì)做一次檢測(cè),但不會(huì)做級(jí)聯(lián)操作,而是直接拒絕操作。

場(chǎng)景思考

知道外鍵是什么后,我們來(lái)思考一個(gè)場(chǎng)景:

現(xiàn)在有一個(gè)電商系統(tǒng),用戶有一個(gè)賬戶id,商品有一個(gè)商品id,這兩個(gè)字段和訂單綁定,此時(shí)訂單id和賬戶表ID構(gòu)成一個(gè)外鍵關(guān)系,同時(shí)和商品表id也構(gòu)成一個(gè)外鍵關(guān)系,那么我每次生成一筆訂單,就需要向另外兩張表查詢檢測(cè)一次數(shù)據(jù),那么就存在幾個(gè)問(wèn)題:

  • 增刪改觸發(fā)這個(gè)查詢操作的性能消耗,服務(wù)器系統(tǒng)是否允許
  • 在其他表查詢會(huì)上需要對(duì)其他表做一個(gè)內(nèi)部鎖,是否存在高并發(fā)死鎖情況
  • 數(shù)據(jù)一致性全部交給數(shù)據(jù)庫(kù)服務(wù)器,數(shù)據(jù)庫(kù)服務(wù)器是否能夠承受

這些問(wèn)題在互聯(lián)網(wǎng)公司會(huì)顯得格外嚴(yán)重,因?yàn)樵L問(wèn)流量大的時(shí)候以上問(wèn)題基本上是完全無(wú)法得到MySQL系統(tǒng)本身解決的

同時(shí)在做分庫(kù)分表設(shè)計(jì)的時(shí)候,外鍵約束就會(huì)顯得格外離譜。

同時(shí)MySQL系統(tǒng)的外鍵設(shè)計(jì)是背離部分SQL標(biāo)準(zhǔn)的

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

對(duì)SQL標(biāo)準(zhǔn)的背離:如果ON UPDATE CASCADE或ON UPDATE SET NULL遞歸更新相同的表,之前在級(jí)聯(lián)過(guò)程中該表一被更新過(guò),它就象RESTRICT一樣動(dòng)作。這意味著你不能使用自引用ON UPDATE CASCADE或者ON UPDATE SET NULL操作。這將阻止級(jí)聯(lián)更新導(dǎo)致的無(wú)限循環(huán)。另一方面,一個(gè)自引用的ON DELETE SET NULL是有可能的,就像一個(gè)自引用ON DELETE CASCADE一樣。級(jí)聯(lián)操作不可以被嵌套超過(guò)15層深。對(duì)SQL標(biāo)準(zhǔn)的背離: 類似一般的MySQL,在一個(gè)插入,刪除或更新許多行的SQL語(yǔ)句內(nèi),InnoDB逐行檢查UNIQUE和FOREIGN KEY約束。按照SQL的標(biāo)準(zhǔn),默認(rèn)的行為應(yīng)被延遲檢查,即約束僅在整個(gè)SQL語(yǔ)句被處理之后才被檢查。直到InnoDB實(shí)現(xiàn)延遲的約束檢查之前,一些事情是不可能的,比如刪除一個(gè)通過(guò)外鍵參考到自身的記錄。

處理

因?yàn)橐陨蠁?wèn)題,我們通常在建模時(shí)隱性設(shè)計(jì)外鍵約束,實(shí)際實(shí)現(xiàn)采用業(yè)務(wù)邏輯模擬外鍵的方式處理,這樣可以解決把一致性全部放在DBA上的性能問(wèn)題,同時(shí)我們可以采用允許臟數(shù)據(jù)存在,然后定時(shí)數(shù)據(jù)清理的方案去保證數(shù)據(jù)處理的分時(shí)性能,避免高峰處理。

這樣的好處:

  • 解決性能問(wèn)題
  • 增加了可擴(kuò)展性,框架遷移不用在數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)部實(shí)現(xiàn)邏輯約束
  • 分庫(kù)分表的時(shí)候方便
  • 不會(huì)在DB層面造成死鎖

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

我覺(jué)得在部分業(yè)務(wù)場(chǎng)景下是可以考慮使用的,回到最開(kāi)始的例子,教務(wù)系統(tǒng)的成績(jī)模塊重要的點(diǎn)不再是性能問(wèn)題,而是高可靠,因?yàn)閷?duì)學(xué)校來(lái)說(shuō),系統(tǒng)存在以下特點(diǎn):

  • 數(shù)據(jù)量較少,一個(gè)學(xué)校學(xué)生最多不超過(guò)10萬(wàn)人,通常在5000-50000這個(gè)區(qū)間內(nèi),對(duì)DB來(lái)說(shuō)這是一個(gè)很小的數(shù)據(jù)量
  • 數(shù)據(jù)不容許出錯(cuò),因?yàn)槌煽?jī)和學(xué)生的人身利益直接掛鉤
  • 能夠進(jìn)行數(shù)據(jù)修改操作的用戶極少,只有教務(wù)處錄入成績(jī)的老師。
  • 如果放在業(yè)務(wù)部分,如果出現(xiàn)student表student_id在第一次被刪除后,未清理score表數(shù)據(jù),這個(gè)student_id短時(shí)間內(nèi)被再次使用,而沒(méi)有做數(shù)據(jù)清理,就容易出現(xiàn)成績(jī)復(fù)用錯(cuò)誤,諸如此類

所以 不得使用外鍵與級(jí)聯(lián),一切外鍵概念必須在應(yīng)用層解決。 大部分情況下正確,但同樣我認(rèn)為需要分業(yè)務(wù)場(chǎng)景解決,并不能一竿子打死。

來(lái)源:為什么大多數(shù)互聯(lián)網(wǎng)公司不用外鍵約束 - JethroYu - 博客園

總結(jié)

以上是生活随笔為你收集整理的mysql 外键_为什么大多数互联网公司不用外键约束的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。