[转] mysql 外键(Foreign Key)的详解和实例

摘要: 外键具有保持数据完整性和一致性的机制,业务处理有着很好的校验作用。目前MySQL只在InnoDB引擎下支持,下面实例下一个小操作来说明下外键的关联操作,用来保持数据的完整性和一致性。

============正文===============
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`;

大家可以自行百度一下,这里就不啰嗦了,截稿!

点击可查看转载 原文出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容