MYSQL中外鍵的知識與應(yīng)用小結(jié)
外鍵(Foreign Key)詳解
基本概念
外鍵是關(guān)系數(shù)據(jù)庫中的一個重要約束條件,它用于建立和強制兩個表之間的關(guān)聯(lián)關(guān)系。外鍵是一個表中的字段(或字段集合),它引用另一個表的主鍵或唯一鍵。
主要特性
- 參照完整性:確保外鍵值必須存在于被引用表的主鍵中,或者為NULL
- 級聯(lián)操作:可以定義級聯(lián)更新和級聯(lián)刪除規(guī)則
- 關(guān)系建立:明確表與表之間的關(guān)聯(lián)方式

如圖所示:具有外鍵的表稱為主表,與外鍵關(guān)聯(lián)的表成為父表
語法示例
CREATE TABLE 訂單 (
訂單ID INT PRIMARY KEY,
客戶ID INT,
訂單日期 DATE,
FOREIGN KEY (客戶ID) REFERENCES 客戶(客戶ID)
);命名解釋
1.CONSTRAINT fk_order_user
- 意思:我要創(chuàng)建一個約束,名字叫
fk_order_user CONSTRAINT= 約束(規(guī)則)fk_order_user= 你給這個規(guī)則起的名字- 命名規(guī)范:
fk_子表_主表 - 這里就是:訂單表 關(guān)聯(lián) 用戶表
- 命名規(guī)范:
作用:方便以后刪除 / 修改這個外鍵。
2.FOREIGN KEY (user_id)
- 意思:在當(dāng)前這張表(子表 / 訂單表)里,
user_id這個字段是外鍵 - 外鍵 = 用來 “去找另一張表” 的字段
作用:告訴數(shù)據(jù)庫:
我這個
user_id不是普通字段,它要關(guān)聯(lián)另一張表。
3.REFERENCES user(id)
- 意思:這個外鍵 參考 / 引用 主表
user里的id字段 REFERENCES= 參考、關(guān)聯(lián)、引用
作用:
訂單表的 user_id 必須是用戶表 id 里已經(jīng)存在的值 不能隨便填,不能填不存在的用戶 ID
三句話總結(jié)(背會就懂)
- CONSTRAINT 名字:給這條關(guān)聯(lián)規(guī)則起個名
- FOREIGN KEY (字段):子表里哪個字段要做關(guān)聯(lián)
- REFERENCES 表 (字段):關(guān)聯(lián)到主表的哪個字段
添加外鍵
外鍵(Foreign Key)是數(shù)據(jù)庫表中的一個或多個字段,用于建立和加強兩個表數(shù)據(jù)之間的鏈接。外鍵約束用于維護(hù)關(guān)系數(shù)據(jù)庫中的引用完整性。
語法格式
在SQL中,添加外鍵的基本語法如下:
ALTER TABLE 子表名稱 ADD CONSTRAINT 外鍵約束名稱 FOREIGN KEY (子表字段) REFERENCES 父表名稱(父表字段);
詳細(xì)步驟
- 確定關(guān)系:
- 明確哪個表是父表(被引用表),哪個是子表(引用表)
- 確定關(guān)聯(lián)字段
- 創(chuàng)建外鍵約束:
- 使用ALTER TABLE語句修改子表
- 指定外鍵約束名稱(可選但推薦)
- 指定子表中的外鍵字段
- 使用REFERENCES關(guān)鍵字指向父表及其主鍵
- 可選參數(shù):
- ON DELETE:指定刪除父表記錄時的行為
- CASCADE:級聯(lián)刪除子表相關(guān)記錄
- SET NULL:將子表相關(guān)記錄設(shè)為NULL
- RESTRICT/NO ACTION:阻止刪除(默認(rèn))
- ON UPDATE:指定更新父表主鍵時的行為
示例場景
假設(shè)我們有兩個表:
departments(部門表):包含dept_id(主鍵), dept_name等字段employees(員工表):包含emp_id, emp_name, dept_id等字段
要為員工表添加指向部門表的外鍵約束:
ALTER TABLE employees ADD CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON DELETE CASCADE ON UPDATE CASCADE;
注意事項
- 父表關(guān)聯(lián)字段必須是主鍵或唯一鍵
- 子表和父表字段數(shù)據(jù)類型必須匹配
- 添加外鍵前確保現(xiàn)有數(shù)據(jù)滿足約束條件
- 外鍵會影響數(shù)據(jù)庫性能,需合理設(shè)計
- 在大型表中添加外鍵可能需要較長時間
應(yīng)用場景
- 維護(hù)數(shù)據(jù)完整性:防止無效數(shù)據(jù)插入
- 實現(xiàn)表間關(guān)聯(lián)查詢
- 自動級聯(lián)更新或刪除相關(guān)記錄
- 建立一對多或多對一關(guān)系
刪除外鍵
如需刪除外鍵約束:
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵約束名稱;

這張圖講的是 MySQL 外鍵(FOREIGN KEY)在 ON DELETE / ON UPDATE 時的五種約束行為,我給你逐個拆解用法、區(qū)別和適用場景。
一、核心概念
這些行為,是定義在 ** 子表(有外鍵的表)的外鍵上,用來規(guī)定: 當(dāng)父表(被引用的表)** 的主鍵 / 唯一鍵被刪除或更新時,子表該如何響應(yīng)。
二、逐個解釋與用法
1.NO ACTION/RESTRICT
- 作用:當(dāng)父表要刪除 / 更新某條記錄時,如果子表里有引用這條記錄的外鍵,則禁止父表操作,拋出錯誤。
- 區(qū)別:在 MySQL 的 InnoDB 引擎中,兩者行為完全一樣,都是 “限制操作”。
- 用法示例
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE RESTRICT ON UPDATE NO ACTION;
- 適用場景: 訂單表引用用戶表時,不允許刪除有訂單的用戶。
2.CASCADE(級聯(lián))
- 作用:父表刪除 / 更新時,子表里對應(yīng)的記錄也跟著一起刪除 / 更新。
- 用法示例
FOREIGN KEY (order_id) REFERENCES order(id) ON DELETE CASCADE ON UPDATE CASCADE;
- 適用場景: 訂單明細(xì)表引用訂單表,刪除訂單時,自動刪除該訂單的所有明細(xì)。
3.SET NULL
- 作用:父表刪除時,子表里對應(yīng)的外鍵字段會被設(shè)置為
NULL。 - 前提:外鍵字段必須允許為
NULL。 - 用法示例
FOREIGN KEY (manager_id) REFERENCES employee(id) ON DELETE SET NULL;
- 適用場景: 部門表引用員工表(manager_id),員工離職時,部門的經(jīng)理字段置空,而不是刪除部門。
4.SET DEFAULT
- 作用:父表變更時,子表的外鍵字段會被設(shè)置為一個預(yù)設(shè)的默認(rèn)值。
- 注意:MySQL 的 InnoDB 引擎不支持,只有部分其他數(shù)據(jù)庫(如 PostgreSQL)支持。
- 在 MySQL 中不要使用這個選項,否則會報錯。
三、關(guān)鍵對比表
表格
| 行為 | 父表刪除 / 更新時 | 子表的反應(yīng) | 限制條件 |
|---|---|---|---|
NO ACTION / RESTRICT | 禁止父表操作 | 不做任何變化 | - |
CASCADE | 允許父表操作 | 同步刪除 / 更新子表對應(yīng)記錄 | - |
SET NULL | 允許父表刪除 | 子表外鍵設(shè)為 NULL | 外鍵字段允許為 NULL |
SET DEFAULT | 允許父表操作 | 子表外鍵設(shè)為默認(rèn)值 | InnoDB 不支持 |
四、實際使用建議
- 優(yōu)先用
RESTRICT/NO ACTION:防止誤刪父表數(shù)據(jù),是最安全的默認(rèn)行為。 CASCADE慎用:會自動刪除子表數(shù)據(jù),容易造成數(shù)據(jù)丟失,只在明確需要級聯(lián)刪除的場景用(如訂單 - 訂單明細(xì))。SET NULL注意空值:業(yè)務(wù)邏輯要能處理外鍵為NULL的情況,避免后續(xù)查詢報錯。- 不要用
SET DEFAULT:MySQL InnoDB 不支持,寫了也沒用。
常見應(yīng)用場景
- 一對多關(guān)系:如客戶與訂單的關(guān)系
- 多對多關(guān)系:通過中間表實現(xiàn)
- 自引用關(guān)系:如員工表中的經(jīng)理也是員工
注意事項
- 外鍵列和被引用列必須具有相同的數(shù)據(jù)類型
- 外鍵約束會影響數(shù)據(jù)庫性能
- 刪除或更新被引用表中的記錄時需要考慮外鍵約束
高級用法
- 復(fù)合外鍵:由多個列組成的外鍵
- 延遲約束檢查:在事務(wù)結(jié)束時才檢查約束
- 禁用外鍵約束:在特定情況下臨時禁用約束
外鍵是維護(hù)數(shù)據(jù)庫完整性的重要機制,合理使用可以確保數(shù)據(jù)的一致性和有效性。
附有關(guān)外鍵的題目:
外鍵面試真題(附參考答案)
1. 什么是外鍵?有什么作用?
參考答案
外鍵(Foreign Key)用于建立表與表之間的關(guān)聯(lián)關(guān)系。
主要作用:
- 保證數(shù)據(jù)一致性
- 防止臟數(shù)據(jù)
- 實現(xiàn)表關(guān)系(一對多等)
例如:
學(xué)生表中的 class_id
引用班級表中的 id。
2. 外鍵和主鍵有什么區(qū)別?
參考答案
| 主鍵 | 外鍵 |
|---|---|
| 唯一標(biāo)識記錄 | 建立表關(guān)系 |
| 不允許重復(fù) | 可以重復(fù) |
| 一般不能為空 | 可以為空 |
| 一個表通常一個主鍵 | 一個表可以多個外鍵 |
3. 外鍵可以引用普通字段嗎?
參考答案
一般不能。
外鍵引用的字段必須:
5. 為什么刪除父表數(shù)據(jù)會失?。?/h3>
參考答案
因為子表存在引用。
例如:
student.class_id = 1
這時刪除:
DELETE FROM class WHERE id = 1;
數(shù)據(jù)庫會阻止刪除。
因為:
父表記錄正在被子表引用。
6. 什么是級聯(lián)刪除?
參考答案
刪除父表數(shù)據(jù)時,自動刪除對應(yīng)子表數(shù)據(jù)。
例如:
ON DELETE CASCADE
刪除班級時:
7. 什么是級聯(lián)更新?
參考答案
當(dāng)父表主鍵變化時:
子表外鍵自動同步修改。
例如:
ON UPDATE CASCADE
8. 為什么互聯(lián)網(wǎng)公司很多不用外鍵?
參考答案
主要原因:
所以:
很多公司:
9. 外鍵一定會提高數(shù)據(jù)庫安全性嗎?
參考答案
會提高數(shù)據(jù)一致性。
但:
因為插入、刪除時需要檢查約束。
10. 外鍵和索引有什么關(guān)系?
參考答案
外鍵用于:
索引用于:
兩者作用不同。
但:
外鍵字段通常會建立索引。
11. 一對多關(guān)系怎么設(shè)計?
參考答案
例如:
設(shè)計:
即:
“多”的一方存外鍵。
12. 多對多關(guān)系怎么設(shè)計?
參考答案
需要第三張中間表。
例如:
學(xué)生選課:
設(shè)計:
student course student_course
中間表:
student_id course_id
13. 下面 SQL 為什么報錯?
CREATE TABLE student(
id INT PRIMARY KEY,
class_id INT,
FOREIGN KEY(class_id)
REFERENCES class(id)
);參考答案
可能原因:
14. 什么情況下適合使用外鍵?
參考答案
適合:
不太適合:
15. truncate 和 delete 對外鍵有什么影響?
參考答案
DELETE
TRUNCATE
- 是主鍵(PRIMARY KEY)
- 或唯一鍵(UNIQUE)
例如:
REFERENCES class(id)
這里的 id 通常是主鍵。
4. 創(chuàng)建外鍵時需要滿足什么條件?
參考答案
必須滿足:
- 兩個字段類型一致
- 長度一致
- 字符集最好一致
- 被引用字段必須是主鍵或唯一鍵
- 存儲引擎必須支持外鍵(如 InnoDB)
- 班級下所有學(xué)生也會刪除。
- 性能損耗
- 分庫分表困難
- 微服務(wù)不方便
- 影響高并發(fā)
- 數(shù)據(jù)庫不加外鍵
- 在代碼層維護(hù)關(guān)系
- 不一定提高系統(tǒng)性能
- 有時反而降低寫入效率
- 維護(hù)關(guān)系
- 提高查詢速度
- 一個班級多個學(xué)生
- 班級表:主鍵
id - 學(xué)生表:
class_id外鍵 - 一個學(xué)生選多門課
- 一門課有多個學(xué)生
- class 表不存在
- class.id 不是主鍵/唯一鍵
- 存儲引擎不支持
- 類型不一致
- 小型項目
- 教學(xué)項目
- 管理系統(tǒng)
- 數(shù)據(jù)一致性要求高
- 超高并發(fā)互聯(lián)網(wǎng)系統(tǒng)
- 逐行刪除
- 會觸發(fā)外鍵檢查
- 直接清空表
- 有外鍵時通常不能直接使用
到此這篇關(guān)于MYSQL中外鍵的知識與應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)mysql外鍵應(yīng)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MySQL數(shù)據(jù)關(guān)聯(lián)之外鍵、表關(guān)系、聯(lián)表查詢實戰(zhàn)詳解
- MySQL 表約束從基礎(chǔ)約束到外鍵關(guān)聯(lián)實戰(zhàn)案例詳解
- MySQL主鍵與外鍵設(shè)計原則 + 實戰(zhàn)案例解析
- MySQL外鍵約束與多表查詢操作方法
- MySQL主鍵與外鍵的基本概念與作用詳解
- MySQL外鍵類型及應(yīng)用場景總結(jié)
- MySQL解決數(shù)據(jù)導(dǎo)入導(dǎo)出含有外鍵的方案
- 深入理解MySQL中的主鍵、超鍵、候選鍵、外鍵
- MySQL刪除表的外鍵約束圖文教程(簡單易懂)
- Mysql添加、刪除、主鍵(外鍵)方法詳細(xì)講解
相關(guān)文章
mysql數(shù)據(jù)庫備份命令分享(mysql壓縮數(shù)據(jù)庫備份)
這篇文章主要介紹了mysql數(shù)據(jù)庫備份常用語句,包括數(shù)據(jù)庫壓縮備份、備份多個MySQL數(shù)據(jù)庫、備份多個MySQL數(shù)據(jù)庫、將數(shù)據(jù)庫轉(zhuǎn)移到新服務(wù)器等語句2014-01-01
MySQL 替換某字段內(nèi)部分內(nèi)容的UPDATE語句
至于字段內(nèi)部分內(nèi)容:比如替換標(biāo)題里面的產(chǎn)品價格,接下來為你詳細(xì)介紹下UPDATE語句的寫法,感興趣的你可以參考下哈,希望可以幫助到你2013-03-03
MYSQL數(shù)據(jù)庫中的現(xiàn)有表增加新字段(列)
MYSQL 增加新字段的sql語句,需要的朋友可以參考下。2010-05-05
揭秘SQL優(yōu)化技巧 改善數(shù)據(jù)庫性能
這篇文章是以 MySQL 為背景,很多內(nèi)容同時適用于其他關(guān)系型數(shù)據(jù)庫,需要有一些索引知識為基礎(chǔ),重點講述如何優(yōu)化SQL,來提高數(shù)據(jù)庫的性能2012-01-01

