大廠為啥不用“外鍵”?!
共 2120字,需瀏覽 5分鐘
·
2024-04-02 23:29
大家在學(xué)習(xí)數(shù)據(jù)庫的過程中一定都接觸過外鍵這個概念,并且在各種課后習(xí)題中外鍵還是一個非常重要的考察內(nèi)容,但是在實際的企業(yè)開發(fā)過程中,你會發(fā)現(xiàn)外鍵是被嚴(yán)格禁止使用的,當(dāng)需要多個表之間進(jìn)行關(guān)聯(lián)時,做法是冗余相關(guān)字段,而不是建立外鍵。
為什么?
什么是外鍵?
兩張表有關(guān)聯(lián)關(guān)系,才會涉及外鍵的概念。舉個例子,有兩張表:
1)學(xué)生表(學(xué)生 id、學(xué)生姓名);
CREATE TABLE `student` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '學(xué)生id',
`name` varchar(256) NOT NULL COMMENT '學(xué)生姓名',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='學(xué)生表';
2)成績表(成績 id、學(xué)生 id,分?jǐn)?shù)),對于成績表來說,學(xué)生 id 就是外鍵。
CREATE TABLE `score` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '成績 id',
`student_id` bigint(20) unsigned NOT NULL COMMENT '學(xué)生id',
`score` int(20) unsigned NOT NULL COMMENT '分?jǐn)?shù)'
PRIMARY KEY (`id`),
KEY `student_id` (`student_id`),
CONSTRAINT `fk_student_id` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成績表';
如上,我們通過 foreign key ... references ... 來定義外鍵,將當(dāng)前表的字段關(guān)聯(lián)到另一張表的某個字段。
外鍵和主鍵一樣,都是一種約束,外鍵約束也稱為引用約束或引用完整性約束):
-
外鍵列必須引用另一個表中的主鍵或唯一鍵列; -
外鍵列必須滿足引用完整性,也就是說,它們包含的值必須存在于被引用表的主鍵或唯一鍵列中。
通俗來說:
-
成績表插入數(shù)據(jù)時,student_id 必須是學(xué)生表已存在的 id; -
學(xué)生表刪除/更新數(shù)據(jù)時,會自動刪除/更新成績表中引用 student.id 的數(shù)據(jù)(級聯(lián))。
為什么不推薦使用外鍵?
阿里的開發(fā)手冊中提到:
【強(qiáng)制】不得使用外鍵與級聯(lián),一切外鍵概念必須在應(yīng)用層解決。
定義外鍵之后,數(shù)據(jù)庫的每次操作都需要去檢查外鍵約束。對于插入來說,影響了插入速度;對于更新來說,級聯(lián)更新是強(qiáng)阻塞,存在數(shù)據(jù)庫更新風(fēng)暴(Database Update Storm)的風(fēng)險。
所謂 Database Update Storm,指的是在高并發(fā)環(huán)境下,多個客戶端同時對數(shù)據(jù)庫進(jìn)行大量的更新操作,存在鎖競爭問題甚至死鎖,從而導(dǎo)致數(shù)據(jù)庫性能急劇下降或完全崩潰。
另外,當(dāng)數(shù)據(jù)量非常大的時候,常見手段是分庫分表,但外鍵通常難以跨越不同數(shù)據(jù)庫來建立聯(lián)系,數(shù)據(jù)的一致性更難維護(hù)。
春招已經(jīng)開始啦,大家如果不做好充足準(zhǔn)備的話,春招很難找到好工作。
送大家一份就業(yè)大禮包,大家可以突擊一下春招,找個好工作!
