mysql 外鍵(foreign key)的詳解和實例

轉自:https://my.oschina.net/sallency/blog/465079

參考:http://blog.sina.com.cn/s/blog_91339bff0100ymc2.html

 . cascade方式 在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄     

 . set null方式 在父表上update/delete記錄時,將子表上匹配記錄的列設爲null 要注意子表的外鍵列不能爲not null      

 . No action方式 如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作       

 . Restrict方式 同no action, 都是立即檢查外鍵約束    

 . Set default方式 父表有變更時,子表將外鍵列設置成一個默認的值 但Innodb不能識別

摘要: 外鍵具有保持數據完整性和一致性的機制,目前MySQL只在InnoDB引擎下支持,下面實例下一個小操作來說明下外鍵的關聯操作,用來保持數據的完整性和一致性。

外鍵具有保持數據完整性和一致性的機制,對業務處理有着很好的校驗作用。

============================白話文簡介=================================

簡單來說,若profile表的uid列作爲外鍵user_profile,參考的主表的列(references)爲user表的id,且聯動刪除更新操作(on delete cascade on update cascade),則user表中刪除id爲1的記錄,會聯動profile表中uid爲1的記錄也被刪除,user表中更新id爲1的記錄爲id = 2,則profile表中uid爲1的記錄也會被聯動更新爲uid = 2,這樣遍保持了數據的一致性

B存在外鍵bfk,以A表的ak作爲參照,則A爲主表,B爲從表,A變動將會影響B中作爲外鍵所對應的記錄

alter table `profile` add constraint `user_profile` foreign key (`uid`) references `user`(`id`) on delete cascade on update cascade;

在profile中爲uid列添加名爲user_profile的外鍵,且此外鍵的參照爲user表的id列,關聯的操作爲刪除和更新

=============================正文====================================

1、表引擎必須爲InnoDB,MyISAM不支持

2、外鍵必須建立索引(可以爲普通、主鍵、唯一,事先不建立的話會自動創建一個普通索引),你要用的外鍵和參照的外表的鍵,

alter table B add constraint `b_foreign_key_name` foreign key (`bfk`) 
references A(`afk`) on delete no action on update no action;


時 b_foreign_key_name 爲外鍵名,bfk字段和afk字段都必須存在索引

3、外表爲約束表,約束着含有外鍵的被約束表,即 B 含有一個以 A 作爲參考表的外鍵,則 A 爲主 B 爲從,弱關聯on delete on update等動作,則 A 變更 B 會被變更,B 怎樣變 A 不必跟隨變動,且表 A 中必須事先存在 B 要插入的數據外鍵列的值,列如 B.bfk作爲外鍵 參照 A.afk ,則 B.bfk插入的值必須是 A.afk 中已存在的

4、把3所的簡單點就是若B有以A作爲參照的外鍵,則B中的此字段的取值只能是A中存在的值,從表B會實時受到主表A的約束,同時若關聯on delete on update等操作則當A中的被參照的字段發生delete或update時,B中的對應的記錄也會發生delete 或 update操作,完整性。

                                                                                                                                                                            

下面我們以一個簡單的學生信息管理系統的數據表做爲實例

                                                                                                                                                                            

先把表和索引加好

//學生表 cid作爲外鍵關聯班級表 pid作爲 檔案表外鍵的關聯 所以這倆貨都得有索引
create table my_student(
	`id` int unsigned not null auto_increment primary key,
	`name` varchar(25) not null comment 'student name',
	`pid` int unsigned not null comment 'student profile id',
	`cid` int unsigned not null comment 'student class id',
	key `cid`(`cid`),
	key `pid`(`pid`)
)engine=InnoDB default charset=utf8 auto_increment=1;
//班級表 id作爲 學生表外鍵的關聯 已爲主鍵索引
create table my_class(
	`id` int unsigned not null auto_increment primary key,
	`cname` varchar(25) not null comment 'class name',
	`info` tinytext not null default ''
)engine=InnoDB default charset=utf8 auto_increment=1;
//檔案表 id作爲外鍵 關聯 學生表 已爲主鍵索引
create table my_profile(
	`id` int unsigned not null auto_increment primary key,
	`pname` varchar(25) not null comment 'profile name',
	`info` tinytext not null default '' comment 'student info',
)engine=InnoDB default charset=utf8 auto_increment=1;


                                                                                                                                                                       

這裏我們將my_student作爲my_profile的外表,即約束表,即my_profile以自身id作爲 外鍵 關聯 以 my_student 的pid字段作爲參照,關聯delete聯動操作,update不做任何操作,如下

alter table my_profile add constraint profile_student foreign key (`id`) references my_student(`pid`) on delete cascade on update no action;


這裏我們將my_class作爲my_student的外表,即約束表,即my_student以自身cid作爲 外鍵 關聯 以 my_class 的id字段作爲參照,關聯update聯動操作,delete不做任何操作,如下

alter table my_student add constraint student_class foreign key (`cid`references my_class(`id`on update cascade on delete no action;

                                                                                                                                                                            

則當我刪除my_student中 id=1 的學生時,其會將my_profile中id爲此學生pid的記錄刪掉

//刪除id爲1的學生記錄,因檔案表以學生表作爲外表約束,且關聯 on delete cascade操作
delete from my_student where id = 1;

這是外鍵機制自身執行的處理動作
delete from my_profile where id = (select pid from my_student where id = 1);
這是外鍵機制自身執行的處理動作


則當我更新my_class中 id=1 的班級爲5時,其會將my_student中cid=1的學生更新爲cid=5

//更新聯動
update my_class set id = 5 where id = 1;

這是外鍵機制自身執行的處理動作
update my_student set cid = 5 where cid = 1;
這是外鍵機制自身執行的處理動作


貼出代碼:

my_profile:

id做爲外鍵,參照my_student以其pid作爲關聯,關聯刪除聯動,更新無動作,則檔案表受學生表的刪除約束,當學生表中id爲xx的記錄被刪除時,檔案表中id爲此記錄pid的記錄也會唄刪除掉。

my_student:

學生表

pid作爲檔案表的外鍵關聯所以要建立key `pid` 索引

以cid作爲外鍵 參照 班級表的id 關聯更新操作 刪除無關聯(用意爲當班級的id發生變動時,學生表中每個學生的cid也會關聯更新,這樣即使班級表中的班級id發生變化,學生所屬班級仍然保持着完整且一致)

my_class:

班級表,id作爲學生表的外鍵參照,爲主鍵索引

實驗開始:

1、刪除學生表中的某個學生,則將其作爲外表參照且關聯刪除聯動操作的檔案表中的記錄也會被刪除掉,關聯關係爲

my_profile.id = my_student.pid的記錄

很容易看懂吧,刪除id爲22的學生時,他的pid爲2,則檔案表裏id爲2的記錄也被關聯刪除了

2、修改班級id,學生表cid外鍵的更新聯動 關聯 班級表中的id,即當我變更班級id時,學生表中的cid也會被更新

很容易看懂吧,四年級的id由4更新爲5時,以其作爲參照表的學生表中屬於四年級的小紅的cid也由4更新爲5。

                                                                                                                                                                            

on delete on update的聯動操作有四種

no action

cascade

set null

restrict

添加外鍵

alter table B add constraint `bfk` foreign key ('fk_column_name') references A('column_name') on delete no action on update no action;


刪除外鍵

alter table B drop foreign key `bfk`;


大家可以自行百度一下,這裏就不囉嗦了,截稿!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章