有些时候,为了保证数据的完整性,我们会选择的使用外键约束,例如教师对应的表和课程表中老师的id,这种时候就要使用外键约束了。

PS:这里不考虑表结构设计,三范式与反范式等设计问题,基于MySQL8.0

语法:

constraint 外键名 foreign key 外键字段 references 主表名(关联字段) [主表记录删除时的动作] [主表记录更新时的动作]

constraint可以省略,只是用来指定外键名

例如:

CREATE TABLE test (
course_id INT (11) NOT NULL AUTO_INCREMENT,
NAME VARCHAR (30) DEFAULT NULL,
PRIMARY KEY (course_id),
CONSTRAINT cour_id_fk FOREIGN KEY (course_id) REFERENCES teacher (teacher_id)
);

或者通过alter添加:

alter table course add constraint course_id_fk foreign key (course_id) references teacher(teacher_id) on delete cascade on update cascade;

PS:关联主表的column必须是索引,如果不是索引无法添加外键约束

做个测试:

mysql> CREATE TABLE test2 (
-> course_id INT (11) NOT NULL AUTO_INCREMENT,
-> identified_no INT(18) UNIQUE,
-> NAME VARCHAR (30) DEFAULT NULL,
-> PRIMARY KEY (course_id)
-> );
Query OK, 0 rows affected (0.03 sec) mysql> CREATE TABLE test1 (
-> course_id INT (11) NOT NULL AUTO_INCREMENT,
-> identified_no INT(18) UNIQUE,
-> NAME VARCHAR (30) DEFAULT NULL,
-> PRIMARY KEY (course_id),
-> CONSTRAINT cour_id1_fk FOREIGN KEY (NAME) REFERENCES test2 (NAME)
-> );
ERROR 1822 (HY000): Failed to add the foreign key constraint. Missing index for constraint 'cour_id1_fk' in the referenced table 'test2'
mysql> drop table if exists test2;
Query OK, 0 rows affected (0.02 sec) mysql> CREATE TABLE test2 (
-> course_id INT (11) NOT NULL AUTO_INCREMENT,
-> identified_no INT(18) UNIQUE,
-> NAME VARCHAR (30) DEFAULT NULL,
-> PRIMARY KEY (course_id),
-> INDEX(NAME)
-> );
Query OK, 0 rows affected (0.03 sec) mysql> CREATE TABLE test1 (
-> course_id INT (11) NOT NULL AUTO_INCREMENT,
-> identified_no INT(18) UNIQUE,
-> NAME VARCHAR (30) DEFAULT NULL,
-> PRIMARY KEY (course_id),
-> CONSTRAINT cour_id1_fk FOREIGN KEY (NAME) REFERENCES test2 (NAME)
-> );
Query OK, 0 rows affected (0.04 sec)

结果:name列如果不是索引,无法作为外键的引用列,当我们添加name为索引,发现添加外键约束成功

外键约束的方式有四种:

1、cascade:

  级联方式,删除/更新父表的某条记录,子表中引用该值的记录会自动被删除/更新

CREATE TABLE `teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1002 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(30) DEFAULT NULL,
`teacher_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `course_id_fk` (`teacher_id`),
CONSTRAINT `course_id_fk` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
mysql> select * from teacher;
+------+-------+
| id | name |
+------+-------+
| 1001 | sam |
| 1002 | jesen |
+------+-------+
2 rows in set (0.00 sec) mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 1 | 语文 | 1001 |
| 2 | 数学 | 1002 |
+----+--------+------------+
2 rows in set (0.00 sec) mysql> update teacher set id=1 where id=1001;  //更新主表的id,从表的外键值会更新
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 1 | 语文 | 1 |
| 2 | 数学 | 1002 |
+----+--------+------------+
2 rows in set (0.00 sec) mysql> delete from teacher where id=1;  //删除主表的id,从表外键值对应的那条数据也会删除
Query OK, 1 row affected (0.00 sec) mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 2 | 数学 | 1002 |
+----+--------+------------+
1 row in set (0.00 sec) mysql> update course set teacher_id=2 where id =1;  //不能直接更新从表的外键
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mysql`.`course`, CONSTRAINT `course_id_fk` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

2、set null:

  设置为null。主表主键值被更新或删除,从表的外键被设置为null。但注意,要求该外键列,没有not null属性约束。

先删除外键,后重建:

mysql> alter table course drop foreign key course_id_fk;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table course add constraint course_id_fk foreign key (teacher_id) references teacher(id) on delete set null on update set null;
Query OK, 1 row affected (0.06 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 1 | 数学 | 1002 |
+----+--------+------------+
1 row in set (0.00 sec) mysql> update teacher set id=1001;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 1 | 数学 | NULL |
+----+--------+------------+
1 row in set (0.00 sec)
mysql> delete from teacher ;
Query OK, 1 row affected (0.00 sec) mysql> select * from course;
+----+--------+------------+
| id | name | teacher_id |
+----+--------+------------+
| 1 | 数学 | NULL |
+----+--------+------------+
1 row in set (0.00 sec)

no action/restrict:

  禁止模式,拒绝父表删除和更新

mysql> alter table course drop foreign key course_id_fk;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0 mysql> alter table course add constraint course_id_fk foreign key (teacher_id) references teacher(id) on delete no action on update restrict;
Query OK, 1 row affected (0.06 sec)
Records: 1 Duplicates: 0 Warnings: 0 mysql> update teacher set id=10012;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`mysql`.`course`, CONSTRAINT `course_id_fk` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON UPDATE RESTRICT) mysql> delete from teacher;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`mysql`.`course`, CONSTRAINT `course_id_fk` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`) ON UPDATE RESTRICT)

默认:也是禁止模式

alter table course add constraint course_id_fk foreign key (teacher_id) references teacher(id);

MySQL系列(十一)--外键约束foreign key的基本使用的更多相关文章

  1. 外键约束 foreign key

    外键约束 :保持数据一致性,完整性实现一对多关系.外键必须关联到键上面去,一般情况是,关联到另一张表的主键 (因为一个表只存一类信息.用外键来做参照,保证数据的一致性,可以减少数据冗余) ##表acr ...

  2. 关于数据库主从表、主键PRIMARY KEY 外键约束 FOREIGN KEY 约束----NOT NULL,DEFAULT,CHECK

    如果由两个列共同组成主键,而且一个子表将主键作为可为空值的外键来继承,就可能得到错误的数据.可在一个外键列中插入有效的值,但在另一个外键列中插入空值.然后,可添加一个数据表检查约束,在可为空的外键中检 ...

  3. mysql 外键(FOREIGN KEY)

    最近有开始做一个实验室管理系统,因为分了几个表进行存储·所以要维护表间的关联··研究了一下MySQL的外键. (1)只有InnoDB类型的表才可以使用外键,mysql默认是MyISAM,这种类型不支持 ...

  4. MySQL(10):实体、实体表和外键(foreign key)

    1.实体        数据库管理系统中的各种用于数据管理方便而设定的各种数据管理对象,如:数据库表.视图.存储过程等都是数据库实体.广义上讲,这些对象中所存储的数据也是数据库实体.因为它们也是确切存 ...

  5. 如何在MySQL中设置外键约束

    引用:http://blog.sina.com.cn/s/blog_53729e4601011wja.html MySql外键设置详解   (1) 外键的使用: 外键的作用,主要有两个:    一个是 ...

  6. MySQL truncate含有外键约束的条目报错

    1.报错信息: Cannot truncate a table referenced in a foreign key constraint 2.出现错误操作: truncate table a1; ...

  7. 【MySQL】MySQL进阶(外键约束、多表查询、视图、备份与恢复)

    约束 外键约束 外键约束概念 让表和表之间产生关系,从而保证数据的准确性! 建表时添加外键约束 为什么要有外键约束 -- 创建db2数据库 CREATE DATABASE db2; -- 使用db2数 ...

  8. 如何在MySQL中设置外键约束以及外键的作用

    1.外键的作用,主要有两个:     一个是让数据库自己通过外键来保证数据的完整性和一致性     一个就是能够增加ER图的可读性 2.外键的配置 1)先创建一个主表,代码如下: #创建表studen ...

  9. SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束。

    SET FOREIGN_KEY_CHECKS=0;在Mysql中取消外键约束.

随机推荐

  1. 多线程编程9认识等待函数WaitForSingleObject

    一下子跳到等待函数 WaitForSingleObject, 是因为下面的 Mutex.Semaphore.Event.WaitableTimer 等同步手段都要使用这个函数; 不过等待函数可不止 W ...

  2. day23_1-re模块之转义字符、分组、方法

    #!/usr/bin/env python# -*- coding:utf-8 -*-# ------------------------------------------------------- ...

  3. iframe 的那些事儿

    项目中有不少地方用到iframe,今儿把使用iframe遇到的一些问题一块儿总结一下. 1.javascript监听iframe加载完成事件 iframe加载过程需要一定时间,这个加载过程常常出现白屏 ...

  4. 锐速与BBR的原理简单解析

    锐速与BBR的原理简单解析  4 前言 昨天,有一位朋友在我的文章下留言说,锐速和BBR不都是一样,是拥塞算法嘛.因为这方面需要讲的东西比较多,所以我还是专门水一篇文章吧. 锐速 参考资料: http ...

  5. php非法输入数据类型

    1.空白输入 2.超长输入(如大于256个字符) 3.特殊字符(如·!@#¥%……&*()—=|.:‘:<>;'"<>?.,) 4.控制字符(如\r\n等) ...

  6. Extjs & Ext.net中的一些属性

    Extjs & Ext.Net 弹出整个浏览器对话框的方法 top.Ext.Msg.alert("值"); top.Ext.Msg.confirm("值" ...

  7. LuoguP3498 [POI2010]KOR-Beads

    呀呀呀,临走10分钟刷一道水题 然而只是记一下第一次hash被卡 各种模数都被卡了... 本来想打双哈希了,后来皮了一下,模数改成了998244353,然后竟然A掉了 正着hash一遍,反着hash一 ...

  8. [记]Cordova安装插件选择插件版本

    在项目中可以使用 cordova plugin add [PLUGIN_ID] 這个命令安装一个cordova插件,这个命令好像是安装插件的最新版本.当需要通过cordova下载这个插件一个特定的版本 ...

  9. SQFREE - Square-free integers

    SQFREE - Square-free integers 求n以内,约数中不包含任意一个平方数的个数,\(n≤10^{14}\). 解 显然为约数计数问题,于是想办法转换为代数问题,不难列出 \[a ...

  10. task code

    using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks ...