mysql外鍵基本功能與用法詳解
本文實(shí)例講述了mysql外鍵基本功能與用法。分享給大家供大家參考,具體如下:
本文內(nèi)容:
- 什么是外鍵
- 外鍵的增加
- 外鍵的修改和刪除
- 外鍵的約束模式
首發(fā)日期:2018-04-12
什么是外鍵:
- 外鍵就是表中存在一個(gè)字段指向另外一個(gè)表的主鍵,那么這個(gè)字段就可以稱為外鍵。
- 一張表可以有多個(gè)外鍵。
- 外鍵用于約束表與表之間的關(guān)系,可以說(shuō)外鍵是表之間的映射關(guān)系,這個(gè)關(guān)系可以幫助我們處理表之間關(guān)系的緊密性和存在性(比如學(xué)生表的cid班級(jí)號(hào)與班級(jí)表的id建立關(guān)聯(lián),cid應(yīng)該不能為不存在的,如果不增加外鍵cid,沒(méi)有建立上關(guān)系,我們就不知道班級(jí)號(hào)不存在。)。
- 或者說(shuō),外鍵是告訴數(shù)據(jù)庫(kù)系統(tǒng),我們所認(rèn)為的關(guān)系,單純的數(shù)據(jù),系統(tǒng)是不知道實(shí)際意義的,外鍵就是告訴系統(tǒng)應(yīng)該如何處理他們的關(guān)系。
- 所以,外鍵的核心是約束。
外鍵的增加:
- 創(chuàng)建外鍵的前提是該字段首先是一個(gè)索引,如果不是的話,創(chuàng)建外鍵是會(huì)創(chuàng)建成一個(gè)普通索引【所以可以不在意】。
- 創(chuàng)建外鍵的另外一個(gè)前提是“指向表”已經(jīng)創(chuàng)建,對(duì)于一個(gè)不存在的表,將無(wú)法使用外鍵對(duì)應(yīng)上。
- 增加的方式:
- 1.在創(chuàng)建表的時(shí)候定義,在所有字段定義結(jié)束后使用foreign key(外鍵字段) references 指向表(主鍵)來(lái) 定義,比如

- 2.也可以修改字段來(lái)增加: alter table 表名 add [constraint 外鍵名字] foreign key(外鍵字段) references 父表(主鍵字段);
- constraint 外鍵名字:可以幫助定義外鍵的名字,但不建議使用,因?yàn)橐笸怄I名都唯一,而使用系統(tǒng)自定義的絕對(duì)不會(huì)重復(fù),
- 1.在創(chuàng)建表的時(shí)候定義,在所有字段定義結(jié)束后使用foreign key(外鍵字段) references 指向表(主鍵)來(lái) 定義,比如
create table student( id int primary key auto_increment, name varchar(15) not null, gender varchar(10) not null, cid int, foreign key(cid) references class(id) );
create table class( id int primary key auto_increment, cname varchar(15) );
補(bǔ)充:
- 在Mysql中,如果存儲(chǔ)引擎不是innodb,那么無(wú)法使外鍵的約束作用生效,即使是能成功增加外鍵。
- 外鍵名不能重復(fù),所以不建議使用constraint 外鍵名字
外鍵的修改與刪除:
- 修改:不能修改外鍵信息,如外鍵指向之類的,只能先刪除再新增。
- 刪除語(yǔ)法:alter table 表名 drop foreign key 外鍵名;
- 這里的外鍵名不是外鍵字段,而是外鍵名。如果沒(méi)有使用constraint來(lái)定義,可以通過(guò)show create來(lái)查看表創(chuàng)建語(yǔ)句中系統(tǒng)定義的外鍵名。

補(bǔ)充:
- 刪除外鍵時(shí),如果使用desc會(huì)看到表結(jié)構(gòu)還有MUL,那是一個(gè)索引。因?yàn)閯?chuàng)建外鍵時(shí),字段會(huì)被創(chuàng)建成一個(gè)索引。如果不想保留,可以使用drop index 字段名 on 表名.
外鍵的約束模式:
- 外鍵是用來(lái)約束表之間的關(guān)系的。
- (約定創(chuàng)建外鍵的表稱為子表,指向的表稱為父表)
- 針對(duì)子表:可以約束子表的插入和修改【這種約束是父表對(duì)子表的約束】
- 涉及到外鍵的插入和修改時(shí),如果外鍵字段找不到對(duì)應(yīng)的匹配那么會(huì)插入\修改失?。ㄏ癫迦脒x課記錄不可能插入一門課程表中沒(méi)有的課程)。
- 比如:

- 針對(duì)父表:可以約束父表的刪除和更新,通常有可以以下幾種約束模式?!具@種約束是子表對(duì)父表的約束】
- 模式:
- strict嚴(yán)格模式:涉及到外鍵的刪除和更新時(shí),如果對(duì)應(yīng)記錄的主鍵數(shù)據(jù)已經(jīng)被子表使用時(shí),那么無(wú)法刪除(像已經(jīng)有人入學(xué)了某個(gè)班級(jí),學(xué)校不可能犯傻去把某個(gè)班級(jí)刪除,只能刪除那些沒(méi)人入學(xué)的班級(jí)。)
- cascade級(jí)聯(lián)模式:涉及到外鍵的刪除和更新時(shí),如果字段已經(jīng)被子表使用,子表中的數(shù)據(jù)會(huì)對(duì)應(yīng)更新(像某個(gè)班改了班號(hào),那么學(xué)生表中的班別都對(duì)應(yīng)更改;如果某個(gè)班被刪除,就刪除對(duì)應(yīng)班的所有學(xué)生)
- set null置空模式:涉及到外鍵的刪除和更新時(shí),如果字段已經(jīng)被子表使用,那么子表中的外鍵數(shù)據(jù)會(huì)置空(像某個(gè)班被刪掉了,不應(yīng)該刪掉所有學(xué)生,而是應(yīng)該給他們先置空再重新分配班別)【子表允許置空的前提是該字段允許為空】
- 其實(shí)可以給不同操作指定不同模式
- 綜上所述(根據(jù)我的那些舉例),實(shí)際上,合適的舉措是刪除時(shí)置空(即使某個(gè)班太垃圾了,想刪除某個(gè)班,但也不應(yīng)該將所有學(xué)生退學(xué),而是將它們分到別的班),修改時(shí)級(jí)聯(lián)(允許更改班號(hào),而且更改會(huì)更新到學(xué)生中)
- 不同操作設(shè)置不同模式的設(shè)置方法(在子表中操作):foreign key(外鍵字段) references 父表(主鍵) on 操作 模式
foreign key(外鍵字段) references 父表 (主鍵) on delete set null on update cascade;
- 模式:
- 針對(duì)子表:可以約束子表的插入和修改【這種約束是父表對(duì)子表的約束】
-- 實(shí)驗(yàn)表結(jié)構(gòu)
create table class(
id int primary key auto_increment,
cname varchar(15)
);
create table student2(
id int primary key auto_increment,
name varchar(15) not null,
gender varchar(10) not null,
cid int,
foreign key(cid) references class(id) on delete set null on update cascade
);
-- 實(shí)驗(yàn)表數(shù)據(jù):
insert into class(cname) values("python"),("linux"),("java"),("html5");
insert into student2(name,gender,cid) values("Alice","female",1);
insert into student2(name,gender,cid) values("John","female",2);
insert into student2(name,gender,cid) values("Jack","female",3);
insert into student2(name,gender,cid) values("Amy","female",4);
select * from student2;
select * from class;
-- 嘗試更新級(jí)聯(lián)
update class set id = 6 where cname="python";
select * from student2; -- 結(jié)果原來(lái)的python的cid=6
-- 嘗試刪除置空
delete from class where cname="java";
select * from student2; -- 結(jié)果原來(lái)的java的cid=null
補(bǔ)充:
- 需要設(shè)置好約束模式,不要在多個(gè)子表中使用不同的約束模式,不然會(huì)沖突。
更多關(guān)于MySQL相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《MySQL查詢技巧大全》、《MySQL常用函數(shù)大匯總》、《MySQL日志操作技巧大全》、《MySQL事務(wù)操作技巧匯總》、《MySQL存儲(chǔ)過(guò)程技巧大全》及《MySQL數(shù)據(jù)庫(kù)鎖相關(guān)技巧匯總》
希望本文所述對(duì)大家MySQL數(shù)據(jù)庫(kù)計(jì)有所幫助。
- mysql外鍵的三種關(guān)系實(shí)例詳解
- Mysql數(shù)據(jù)庫(kù)中數(shù)據(jù)表的優(yōu)化、外鍵與三范式用法實(shí)例分析
- MySQL創(chuàng)建數(shù)據(jù)表并建立主外鍵關(guān)系詳解
- MySQL外鍵約束常見(jiàn)操作方法示例【查看、添加、修改、刪除】
- MySQL無(wú)法創(chuàng)建外鍵的原因及解決方法
- MySQL刪除有外鍵約束的表數(shù)據(jù)方法介紹
- MySQL刪除表的時(shí)候忽略外鍵約束的簡(jiǎn)單實(shí)現(xiàn)
- MySQL添加外鍵時(shí)報(bào)錯(cuò):1215 Cannot add the foreign key constraint的解決方法
- MySQL使用外鍵實(shí)現(xiàn)級(jí)聯(lián)刪除與更新的方法
- Mysql表創(chuàng)建外鍵報(bào)錯(cuò)解決方案
相關(guān)文章
mysql 5.7.17 安裝配置方法圖文教程(ubuntu 16.04)
這篇文章主要為大家分享了ubuntu 16.04下mysql 5.7.17 安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
MySQL對(duì)相同字段創(chuàng)建不同索引解析
這篇文章主要為大家介紹了MySQL?對(duì)相同字段創(chuàng)建不同索引解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
MySQL派生表合并優(yōu)化的原理和實(shí)現(xiàn)過(guò)程
本文從一個(gè)案例出發(fā)梳理了MySQL派生表合并優(yōu)化的流程實(shí)現(xiàn)和優(yōu)化原理,并對(duì)優(yōu)化前后同一條SQL語(yǔ)句在代碼層面的類實(shí)例映射關(guān)系進(jìn)行了對(duì)比,這篇文章主要介紹了MySQL派生表合并優(yōu)化的原理和實(shí)現(xiàn),需要的朋友可以參考下2024-07-07
MySQL備份時(shí)排除指定數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了MySQL備份時(shí)排除指定數(shù)據(jù)庫(kù)的方法的相關(guān)資料,需要的朋友可以參考下2016-03-03
淺談MySQL中g(shù)roup_concat()函數(shù)的排序方法
下面小編就為大家?guī)?lái)一篇淺談MySQL中g(shù)roup_concat()函數(shù)的排序方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
MySQL之使用UNION和UNION ALL合并兩個(gè)或多個(gè)SELECT語(yǔ)句的結(jié)果集
這篇文章主要介紹了MySQL之使用UNION和UNION ALL合并兩個(gè)或多個(gè)SELECT語(yǔ)句的結(jié)果集,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
基于ubuntu中使用mysql實(shí)現(xiàn)opensips用戶認(rèn)證的解決方法
本篇文章小編為大家介紹,基于ubuntu中使用mysql實(shí)現(xiàn)opensips用戶認(rèn)證的解決方法。需要的朋友參考下2013-04-04

