mysql之外键
本文内容:
- 什么是外键
- 外键的增加
- 外键的修改和删除
- 外键的约束模式
首发日期:2018-04-12
什么是外键:
- 外键就是表中存在一个字段指向另外一个表的主键,那么这个字段就可以称为外键。
- 一张表可以有多个外键。
- 外键用于约束表与表之间的关系,可以说外键是表之间的映射关系,这个关系可以帮助我们处理表之间关系的紧密性和存在性(比如学生表的cid班级号与班级表的id建立关联,cid应该不能为不存在的,如果不增加外键cid,没有建立上关系,我们就不知道班级号不存在。)。
- 或者说,外键是告诉数据库系统,我们所认为的关系,单纯的数据,系统是不知道实际意义的,外键就是告诉系统应该如何处理他们的关系。
- 所以,外键的核心是约束。
外键的增加:
- 创建外键的前提是该字段首先是一个索引,如果不是的话,创建外键是会创建成一个普通索引【所以可以不在意】。
- 创建外键的另外一个前提是“指向表”已经创建,对于一个不存在的表,将无法使用外键对应上。
- 增加的方式:
- 1.在创建表的时候定义,在所有字段定义结束后使用foreign key(外键字段) references 指向表(主键)来 定义,比如
- 2.也可以修改字段来增加: alter table 表名 add [constraint 外键名字] foreign key(外键字段) references 父表(主键字段);
- constraint 外键名字:可以帮助定义外键的名字,但不建议使用,因为要求外键名都唯一,而使用系统自定义的绝对不会重复,
- 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)
- );
补充:
- 在Mysql中,如果存储引擎不是innodb,那么无法使外键的约束作用生效,即使是能成功增加外键。
- 外键名不能重复,所以不建议使用constraint 外键名字
外键的修改与删除:
- 修改:不能修改外键信息,如外键指向之类的,只能先删除再新增。
- 删除语法:alter table 表名 drop foreign key 外键名;
- 这里的外键名不是外键字段,而是外键名。如果没有使用constraint来定义,可以通过show create来查看表创建语句中系统定义的外键名。
补充:
- 删除外键时,如果使用desc会看到表结构还有MUL,那是一个索引。因为创建外键时,字段会被创建成一个索引。如果不想保留,可以使用drop index 字段名 on 表名.
外键的约束模式:
- 外键是用来约束表之间的关系的。
- (约定创建外键的表称为子表,指向的表称为父表)
- 针对子表:可以约束子表的插入和修改【这种约束是父表对子表的约束】
- 涉及到外键的插入和修改时,如果外键字段找不到对应的匹配那么会插入\修改失败(像插入选课记录不可能插入一门课程表中没有的课程)。
- 比如:
- 针对父表:可以约束父表的删除和更新,通常有可以以下几种约束模式。【这种约束是子表对父表的约束】
- 模式:
- strict严格模式:涉及到外键的删除和更新时,如果对应记录的主键数据已经被子表使用时,那么无法删除(像已经有人入学了某个班级,学校不可能犯傻去把某个班级删除,只能删除那些没人入学的班级。)
- cascade级联模式:涉及到外键的删除和更新时,如果字段已经被子表使用,子表中的数据会对应更新(像某个班改了班号,那么学生表中的班别都对应更改;如果某个班被删除,就删除对应班的所有学生)
- set null置空模式:涉及到外键的删除和更新时,如果字段已经被子表使用,那么子表中的外键数据会置空(像某个班被删掉了,不应该删掉所有学生,而是应该给他们先置空再重新分配班别)【子表允许置空的前提是该字段允许为空】
- 其实可以给不同操作指定不同模式
- 综上所述(根据我的那些举例),实际上,合适的举措是删除时置空(即使某个班太垃圾了,想删除某个班,但也不应该将所有学生退学,而是将它们分到别的班),修改时级联(允许更改班号,而且更改会更新到学生中)
- 不同操作设置不同模式的设置方法(在子表中操作):foreign key(外键字段) references 父表(主键) on 操作 模式
- foreign key(外键字段) references 父表 (主键) on delete set null on update cascade;
- -- 实验表结构
- 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
- );
- -- 实验表数据:
- 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;
- -- 尝试更新级联
- update class set id = 6 where cname="python";
- select * from student2; -- 结果原来的python的cid=6
- -- 尝试删除置空
- delete from class where cname="java";
- select * from student2; -- 结果原来的java的cid=null
补充:
- 需要设置好约束模式,不要在多个子表中使用不同的约束模式,不然会冲突。
mysql之外键的更多相关文章
- MySQL之外键约束
MySQL之外键约束 MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: [CONSTRAINT [symbo ...
- MySQL之外键、主键、自增
1.创建外键 create table userinfo( uid int auto_increment primary key, name varchar(32), department_id in ...
- MySQL之外键、联合查询、子查询
外键(foreign key): 外面的键(键不在自己表中),如果一张表中有一个字段(非主键)指向另外一张表的主键,那么将该字段称之为外键. 外键可以在创建表的时候或者创建表之后增加(但是要考虑数据的 ...
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- 浅谈MySQL外键
http://www.xiaoxiaozi.com/2009/07/12/1158/ 像MySQL这样的关系型数据库管理系统,它们的基础是在数据库的表之间创建关系的能力.通过方便地在不同表中建立记录到 ...
- MySQL主键设计盘点
目录 主键定义 主键设计和应用原则 主键生成策略 自增ID UUID 自建的id生成器 Twitter的snowflake算法 @ 最近在项目中用了UUID的方式生成主键,一开始只是想把这种UUID的 ...
- mysql 外键约束备注
梳理mysql外键约束的知识点. 1.mysql外键约束只对InnoDb引擎有效: 2.创建外键约束如下: DROP TABLE IF EXISTS t_demo_product; CREATE TA ...
- MySQL外键之级联
简介 MySQL外键起到约束作用,在数据库层面保证数据的完整性.例如使用外键的CASCADE类型,当子表(例如user_info)关联父表(例如user)时,父表更新或删除时,子表会更新或删除记录,这 ...
- PowerDesigner 15设置mysql主键自动增长及基数
PowerDesigner 15设置mysql主键自动增长及基数 1.双击标示图,打开table properties->columns, 如图点击图标Customize Columns an ...
随机推荐
- [Shell]sed命令在MAC和Linux下的不同使用方式
---------------------------------------------------------------------------------------------------- ...
- 新生命团队netcore服务器免费开放计划
为了便于大家学习测试netcore,我们计划提供1~3台公网Linux服务器(CentOS/Ubuntu),1vCPU+1G内存+100Mbps,为期1年,每周重置系统修改一次密码.对使用者要求如下: ...
- Dijkstra——单源最短路径
算法思想 ①从一个源点开始,找距离它最近的点顶点v ②然后以顶点v为起点,去找v能到达的顶点w,即v的邻居 比较源点直接到 v的距离和(源点到v的距离+v到w的距离) 若大于后者则更新源点的到w的开销 ...
- Go语言学习笔记(六) [包]
日期:2014年7月30日 1.定义:包时函数和数据的集合.使用package关键字定义一个包,文件名不需要与包名一致,包名约定使用小写字符,Go包可以由多个文件组成,但是需要使用相同的packa ...
- 翻译:DECLARE Variable(已提交到MariaDB官方手册)
本文为mariadb官方手册:DECLARE Variable的译文. 原文:https://mariadb.com/kb/en/library/declare-variable/我提交到MariaD ...
- 翻译:low_priority和high_priority(已提交到MariaDB官方手册)
本文为mariadb官方手册:HIGH_PRIORITY and LOW_PRIORITY的译文. 原文:https://mariadb.com/kb/en/high_priority-and-low ...
- JavaScript 系列博客(五)
JavaScript 系列博客(五) 前言 本篇博客学习 js 选择器来控制 css 和 html.使用事件(钩子函数)来处理事件完成后完成指定功能以及js 事件控制页面内容. js 选择器 在学习 ...
- Apollo 9 — adminService 主/灰度版本发布
目录 Controller 层 Service 层 publish 方法 发送 ReleaseMessage 消息 总结 1. Controller 层 主版本发布即点击主版本发布按钮: 具体接口位置 ...
- [转]c# System.IO.Ports SerialPort Class
本文转自:https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?redirectedfrom=MSDN& ...
- 从零开始学安全(十六)● Linux vim命令
游标控制 h 游标向左移 j 游标向下移 k 游标向上移 l (or spacebar) 游标向右移 w 向前移动一个单词 b 向后移动一个单词 e 向前移动一个单词,且游标指向单词的末尾 ( 移到当 ...