简介

MySQL外键起到约束作用,在数据库层面保证数据的完整性。例如使用外键的CASCADE类型,当子表(例如user_info)关联父表(例如user)时,父表更新或删除时,子表会更新或删除记录,这个过程是数据库层面完成的。早期企业系统数据库设计里面比较多,虽说帮程序员节省了delete、update操作,实际上增加了潜规则,也增加了软件复杂度,也会会减弱性能。

所以在应用程序设计中,我们应尽量在应用层保证数据的完整性(如使用事务处理机制),而不是数据库层面。

下面对MySQL的外键进行介绍。

MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。在创建索引的时候,可以指定在删除、更新父表时,对子表进行的相应操作,包括RESTRICT、NO ACTION、SET NULL和CASCADE。

  • RESTRICT和NO ACTION相同,是指在子表有关联记录的情况下父表不能更新;
  • CASCADE表示父表在更新或者删除时,更新或者删除子表对应记录;
  • SET NULL则是表示父表在更新或者删除的时候,子表的对应字段被SET NULL。

示例

因为只有InnoDB引擎才允许使用外键,所以,我们的数据表必须使用InnoDB引擎。

创建数据库:

Create database test;

创建两个表,其中第一个表的”id”是第二个表(userinfo)的外键:

CREATE TABLE `user` (
`id` int(4) NOT NULL,
`sex` enum('f','m') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `userinfo` (
`sn` int(4) NOT NULL AUTO_INCREMENT,
`userid` int(4) NOT NULL,
`info` varchar(20) DEFAULT NULL,
PRIMARY KEY (`sn`),
KEY `userid` (`userid`),
CONSTRAINT `userinfo_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意:

1、存储引擎必须使用InnoDB引擎;

2、外键必须建立索引;

3、外键绑定关系这里使用了“ ON DELETE CASCADE ” “ON UPDATE CASCADE”,意思是如果外键对应数据被删除或者更新时,将关联数据完全删除或者相应地更新。更多信息请参考MySQL手册中关于InnoDB的文档。

好,接着我们再来插入数据测试:

INSERT INTO `user` (`id`,`sex`)
VALUES ('1', 'f'), ('2', 'm'), ('3', 'f'); INSERT INTO `userinfo` (`sn`,`userid`,`info`)
VALUES ('1', '1', '2005054dsf'),
('2', '1', 'fdsfewfdsfds'),
('3', '1', 'gdsgergergrtre'),
('4', '2', 'et34t5435435werwe'),
('5', '2', '435rtgtrhfghfg'),
('6', '2', 'ret345tr4345'),
('7', '3', 'fgbdfvbcbfdgr'),
('8', '3', '45r2343234were'),
('9', '3', 'wfyhtyjtyjyjy');

我们先看一下当前数据表的状态:

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| user |
| userinfo |
+----------------+
2 rows in set (0.00 sec)

User表中的数据:

mysql> select * from user;
+----+------+
| id | sex |
+----+------+
| 1 | f |
| 2 | m |
| 3 | f |
+----+------+
3 rows in set (0.00 sec)

Userinfo表中的数据:

mysql> select * from userinfo;
+----+--------+-------------------+
| sn | userid | info |
+----+--------+-------------------+
| 1 | 1 | 2005054dsf |
| 2 | 1 | fdsfewfdsfds |
| 3 | 1 | gdsgergergrtre |
| 4 | 2 | et34t5435435werwe |
| 5 | 2 | 435rtgtrhfghfg |
| 6 | 2 | ret345tr4345 |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
+----+--------+-------------------+
9 rows in set (0.00 sec)

对于建立以上不表,相信对大家也没什么难度了。好的,下面我们就要试验我们的级联删除功能了。

我们将删除user表中id为2的数据记录,看看userinfo表中userid为2的相关子记录是否会自动删除:

mysql> delete from `user` where `id`='2';
Query OK, 1 row affected (0.03 sec) mysql> select * from user;
+----+------+
| id | sex |
+----+------+
| 1 | f |
| 3 | f |
+----+------+
2 rows in set (0.00 sec)

再看看userinfo表中已经没有userid为2的3条数据记录了,对应数据确实自动删除了!

mysql> select * from userinfo;
+----+--------+----------------+
| sn | userid | info |
+----+--------+----------------+
| 1 | 1 | 2005054dsf |
| 2 | 1 | fdsfewfdsfds |
| 3 | 1 | gdsgergergrtre |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
+----+--------+----------------+
6 rows in set (0.00 sec)

更新的操作也类似,因为我们在前面建表的时候已经定义外键删除、更新操作都是CASCADE,所以在这里可以直接测试数据。

将user表中原来id为1的数据记录更改为id为4,执行如下:

mysql> update user set id=4 where id='1';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0

现在去看看两个表中是数据是否发生了变化:

mysql> select * from user;
+----+------+
| id | sex |
+----+------+
| 3 | f |
| 4 | f |
+----+------+
2 rows in set (0.00 sec) mysql> select * from userinfo;
+----+--------+----------------+
| sn | userid | info |
+----+--------+----------------+
| 1 | 4 | 2005054dsf |
| 2 | 4 | fdsfewfdsfds |
| 3 | 4 | gdsgergergrtre |
| 7 | 3 | fgbdfvbcbfdgr |
| 8 | 3 | 45r2343234were |
| 9 | 3 | wfyhtyjtyjyjy |
+----+--------+----------------+
6 rows in set (0.00 sec)

比较原来的表可以发现它们的确已经更新成功了,测试完成!!!这也就实现了用外键对多个相关联的表做同时删除、更新的操作,从而保证了数据的一致性。

注意:当使用了外键后,使用truncate命令去清空父表数据时,会提示操作出错,这时候应该先去删除字表的数据。

示例部分内容来自:

MySQL使用外键实现级联删除与更新的方法_Mysql_脚本之家

http://www.jb51.net/article/88148.htm

MySQL外键之级联的更多相关文章

  1. MySQL外键及级联删除 && 表的存储引擎与创建索引 && 删除数据库和表

    Messages表: mysql>create table Messages( ->message_id int auto_increment primary key, ->user ...

  2. MySQL外键设置 级联删除

    . cascade方式在父表上update/delete记录时,同步update/delete掉子表的匹配记录 . set null方式在父表上update/delete记录时,将子表上匹配记录的列设 ...

  3. mysql外键策略

    1.外键 建表时添加外键:constraint 外键名 foreign key 从表字段 references 主表字段 级联操作 create table dage( create table xi ...

  4. [原创]MYSQL中利用外键实现级联删除和更新

    MySQL中利用外键实现级联删除.更新 MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引.在创建索引的时候,可以指定 ...

  5. mysql 外键约束及表关联

    一.MYSQL中的约束 1.主键:primary key 唯一非空的特性并且可以优化查询速度 2.外键:foreign key 外键的作用保证2个或2个以上的数据表的数据一致性和完整性 3.唯一:un ...

  6. mysql外键使用和事物使用

    mysql外键功能主要是为了保证关联表数据的一致性,主要目的是控制存储在外键表中的数据. 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有 客户号,客户名称 b表中存 ...

  7. MYSQL 外键 on语句 多表查询

    外键约束 创建外键 --- 每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任 ----主表 CREATE TABLE ClassCharger( id TINYINT PRIMARY KE ...

  8. mysql外键约束总结

    总结三种MySQL外键约束方式 如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是 ...

  9. MYSQL - 外键、约束、多表查询、子查询、视图、事务

    MYSQL - 外键.约束.多表查询.子查询.视图.事务 关系 创建成绩表scores,结构如下 id 学生 科目 成绩 思考:学生列应该存什么信息呢? 答:学生列的数据不是在这里新建的,而应该从学生 ...

随机推荐

  1. iOS 面试题搜集

    1.#import和#include的区别,@class代表什么? 2.浅拷贝和深拷贝区别是什么? 3.Objective-C中类别和类扩展的区别? 4.Objective-C堆和栈的区别? 5.内存 ...

  2. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  3. Devexpress

    1.隐藏最上面的GroupPanel gridView1.OptionsView.ShowGroupPanel=false; 2.得到当前选定记录某字段的值 sValue=Table.Rows[gri ...

  4. 谈 CSS 模块化

    以前看过模块化的相关资料以及解释,对模块化有了一个表皮的了解,自己也做了一些相关的实践,由于接触到的项目交小,所以也没能更好的去体现和理解模块化,但总体还是有那么一些感悟,但是如果要说怎么才能算是好的 ...

  5. [IOS]使用了cocoapods 抱错Pods was rejected as an implicit dependency for ‘libPods.a’ because its architectures ......

    Pods was rejected as an implicit dependency for ‘libPods.a’ because its architectures ‘i386’ didn’t ...

  6. 利用闭包实现多次ajax请求只执行最后一次

    点一个按钮,则向服务器请求资源,不作处理时,多次点击后会有很多个请求在等待.我们知道一般我们用ajax是异步请求,那么我们快速重复点击一个按钮得到的结果其实我们并不知道是哪次点击的结果可能是第一次可能 ...

  7. ps 实例部分

    实例篇1:将不同图片通过阀值转换成黑白色人物头像 图像-黑白-曲向-阀值 本图像-复制-粘贴

  8. nginx-(/usr/local/nginx)配置编译

    ./configure \ --prefix=/usr/local/nginx \ --sbin-path=/usr/local/nginx/sbin/nginx \ --conf-path=/usr ...

  9. webserver几个例子

    刚刚学习了web服务,实现了发布和调用电话号码归属地查询,下面我简单的说一下 第一个方法利用网页实现号码查询: 首先进入http://www.webxml.com.cn/网站 然后点这个 输入手机号码 ...

  10. 关于ubuntu16.04中mysql root登陆不了的情况下(大多是未设置密码的情况)

    1.先将当前用户改成 root用户:sudo su 2.进入安装路径,我的是:cd /etc/mysql/ 3.打开debian.cnf : gedit debian.cnf 4.找到:user pa ...