外键约束

创建外键

前面讲的表单查询都是一张表,但项目中表与表之间是有关联的,比如我们创建的学生表,他们可能在不同班级,不同班级有不同的班主任,他们之间的关系大概是这样的:每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任。所以创建一张班主任的表,这张表应该是主表,学生的那张表是子表,需要添加班主任信息:

CREATE TABLE Classhost(

       id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean
);
INSERT INTO Classhost (name,age,is_marriged) VALUES ("丽丽",22,0),
("莉莉",24,0),
("李丽",22,0),
("李莉",20,0);
CREATE TABLE student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
host_id TINYINT
)ENGINE=INNODB; INSERT INTO Student(name,host_id) VALUES ("pengfy",2),
("pyq",4),
("xiaojiang",1),
("pyq2",3),
("pengfy2",1),
("pyq3",3),
("lily",2);

创建好了两张表如下:

现在假设丽丽辞职了,我们试一下删除名字叫丽丽的班主任:

delete from classhost where name="丽丽";

还真的删掉了,那现在看看学生表有没有什么变化:

发现xiaojaing和pengfy2的班主任id还是1,这显然是不合适的,一个班主任走了,学生信息也要变化,要么分到别的班,要么一起走(特别喜欢这个班主任),大家也可是试一下在删除班主任后,在学生表里面插入一条学生信息,host_id设为1,也是OK的。这两种情况显示不合理,那么这个时候就要引入外键这个概念了,现在给学生的表加上一个外键,首先要找到两张表关联的地方,就是学生表里面host_id和老师表里面的id是关联的,那我们新建一下学生表2:

CREATE TABLE student2(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
host_id TINYINT, --切记:作为外键一定要和关联主键的数据类型保持一致
FOREIGN KEY(host_id) REFERENCES classhost(id)
)ENGINE=INNODB; INSERT INTO Student2(name,host_id) VALUES ("pengfy",2),
                                            ("pyq",4),
                                            ("xiaojiang",4),
                                            ("pyq2",3),
                                            ("pengfy2",4),
                                            ("pyq3",3),
                                            ("lily",2);

这里新的学生信息也要改一下,把id为1的要改成其他的,不然会报错。现在再试一下,删掉id为2的班主任:

delete from classhost where id=2;

报错了,不让删除了,因为外键约束了,报错信息如下:

 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`student2`, CONSTRAINT `student2_ibfk_1` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))

再试一下给id=1的老师加一个学生,看是否能添加成功:

insert into student2(name,host_id) values ('lucy',1);
报错信息:
Cannot add or update a child row: a foreign key constraint fails (`test`.`student2`, CONSTRAINT `student2_ibfk_1` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))

同样报错了 ,看一下报错信息里面有个东西,CONSTRAINT `student2_ibfk_1`这个东西我没有写过,后面的FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))才是我写的,那这个是什么呢?这个是外键名称,你不自定义的时候,会默认给你加上一个,所以给一个表增加一个外键完整的写法是这样的:

ALTER TABLE student  ADD CONSTRAINT anyname
FOREIGN KEY(host_id)
REFERENCES classhost(id);

试着给我们学生表1增加一个外键:

 Cannot add or update a child row: a foreign key constraint fails (`test`.`#sql-1110_2`, CONSTRAINT `anyname` FOREIGN KEY (`host_id`) REFERENCES `classhost` (`id`))

也报错了,这是为什么呢?因为老师里面已经没有id=1的了,而学生表还存在,看来要修改一下学生表才行:

第三个和第五个改成4好了,

update student set host_id=4 where id=3 or id =5;

再试一下增加外键,看一下表结构:

添加成功,那么能增加就能删除嘛,试一下删除这个外键:

 ALTER TABLE student DROP FOREIGN KEY anyname;

查看是否删除成功:

已经找不到外键了,删除成功喽。那现在的问题就是主表怎么正常删除数据,并且把子表的数据也一并删除。这就涉及下面要讲的INNODB支持的ON语句。

INNODB支持的ON语句

外键约束对子表的含义:   如果在父表中找不到候选键,则不允许在子表上进行insert/update
    外键约束对父表的含义: 在父表上进行update/delete以更新或删除在子表中有一条或多条对应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的on update/on delete子句

innodb支持的四种方式

1.cascade方式

      在父表上update/delete记录时,同步update/delete掉子表的匹配记录,外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除,比如刚才在删除班主任的同事,也把学生删除,就应该在主键中加上一段ON DELETE CASCADE:

FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE CASCADE

      我们再给student加上这么一个外键:

ALTER TABLE student  ADD CONSTRAINT anyname
FOREIGN KEY(host_id)
REFERENCES classhost(id)
ON DELETE CASCADE;

同时我们也要把student2这张表删除,因为主表也和这个表绑定了,外键没改到时候删除主表还是会报错的,删掉之后,试一下删除classhost表里面的一个内容:

成功了,没有报错啊,看看子表里面,原先我们的子表id=1和id=7都是host_id=2的:

      现在子表里面绑定了host_id=2的信息也都一起删除了,除了这种,还有以下三种情况。

2.set null方式

      在父表上update/delete记录时,将子表上匹配记录的列设为null,要注意子表的外键列不能为not null

FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
ON DELETE SET NULL

      有兴趣可以试一下这种方式,就不演示了。

3.Restrict方式

       拒绝对父表进行删除更新操作,这个很少用,相当于不让sql报错,了解一下就行了。

4.No action方式

      在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作,这个也作一个了解就行。

mysql数据库基本操作(六)的更多相关文章

  1. day39 mysql数据库基本操作

    什么是数据库 用来存储数据的仓库 数据库可以在硬盘及内存中存储数据 主要学习硬盘中存储数据,因为内存中的数据总有一天会丢失 数据库与文件存储数据区别 (公司的开发是综合内容的) 数据库本质也是通过文件 ...

  2. (三)mysql数据库基本操作

    (1)SQL语句:结构化查询语句 DDL语句 数据定义语言:数据库丶表丶视图丶索引丶存储过程丶函数丶create drop alter DML语句 数据库操作语言:插入数据insert,删除数据del ...

  3. mysql数据库基本操作sql语言

    mysql的启动与关闭 启动 /etc/init.d/mysql start 多实例使用自建脚本启动 2种关闭数据库方法 mysqladmin -uroot -p密码 shutdown #优雅关闭/e ...

  4. Django/MySql数据库基本操作&ORM操作

    数据库配置: #第一步在settings里面 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbna ...

  5. Mysql数据库基本操作 (一)

    1.使用mysql数据库的必备要素 a. 安装MySQL服务端 b. 安装MySQL客户端 c. [客户端]连接[服务端] d. [客户端]发送命令给[服务端MySQL]服务的接受命令并执行相应操作( ...

  6. mysql数据库基本操作以及获取数据库强大帮助文档

    MySQL数据库强大帮助文档 mysql 中help等价于\h或者? mysql> ? create database;(查看创建数据库的语法) mysql> ? drop databas ...

  7. Weka里如何将arff文件或csv文件批量导入MySQL数据库(六)

    这里不多说,直接上干货! 前提博客是 Weka中数据挖掘与机器学习系列之数据格式ARFF和CSV文件格式之间的转换(四) 1.将arff文件批量导入MySQL数据库 我在这里,arff文件以Weka安 ...

  8. MySQL数据库 基本操作语句

    操作MySQL数据库 1.创建数据库 create database 数据库名: 2.查看数据库 show databases: 3.选择指定数据库 use 数据库名: 4.删除数据库 drop da ...

  9. MySQL数据库笔记六:数据定义语言及数据库的备份和修复

    1. MySQL中的函数 <1>加密函数 password(str) 该函数可以对字符串str进行加密,一般情况下,此函数给用户密码加密. select PASSWORD('tlxy666 ...

  10. MySQL数据库基本操作以及SQL语句

    连接mysql的语法 mysql -u用户名 -p密码 [-h主机名] [-P端口号] 在一个mysql服务器中, 可以有多个mysql数据库(本质是一个文件夹) 在一个mysql数据库中, 可以有多 ...

随机推荐

  1. 使用Spark Streaming + Kudu + Impala构建一个预测引擎

    随着用户使用天数的增加,不管你的业务是扩大还是缩减了,为什么你的大数据中心架构保持线性增长的趋势?很明显需要一个稳定的基本架构来保障你的业务线.当你的客户处在休眠期,或者你的业务处在淡季,你增加的计算 ...

  2. HDU 5739 Fantasia 双连通分量 树形DP

    题意: 给出一个无向图,每个顶点有一个权值\(w\),一个连通分量的权值为各个顶点的权值的乘积,一个图的权值为所有连通分量权值之和. 设删除顶点\(i\)后的图\(G_i\)的权值为\(z_i\),求 ...

  3. WEBs

    http://www.cnblogs.com/wupeiqi/articles/5341480.html 请求方式8种: 1.GET:请求指定页面信息,并返回实体 2.POST:向指定资源提交数据进行 ...

  4. laravel5.2总结--文件上传

    1 配置 文件系统的配置文件在 config/filesystems.php 文件中,此处我们新建一个uploads本地磁盘空间用于存储上传的文件,具体配置项及说明如下: <?php retur ...

  5. mongo命令

    安装mongo http://docs.mongodb.org/master/tutorial/install-mongodb-on-redhat-centos-or-fedora-linux/ 启动 ...

  6. Python-S9——Day115-Flask Web框架

    01 当日内容概要 1 当日内容概要 1.1 Flask基础: 1.2 Web框架包含的基础组件: 1.2.1 路由.视图函数.模板渲染: 1.3 Flask配置文件: 1.4 Flask的路由系统: ...

  7. selenium定位下拉菜单好文

    http://www.cnblogs.com/nbkhic/archive/2011/10/23/2221726.html 定位下拉菜单

  8. File(IO流)

    import java.io.File; import java.io.IOException; import org.junit.Test; /** *java.io.File类 *1.凡是与输入输 ...

  9. BZOJ4737 组合数问题 【Lucas定理 + 数位dp】

    题目 组合数C(n,m)表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3)三个物品中选择两个物品可以有( 1,2),(1,3),(2,3)这三种选择方法.根据组合数的定义,我们可以给 ...

  10. BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】

    题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j- ...