有些时候,为了保证数据的完整性,我们会选择的使用外键约束,例如教师对应的表和课程表中老师的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. 训练计划Day1

    Day1:二分答案,三分查找,快速幂,欧拉筛素数 | 题目:火星人,Bridge,GCD,Prime Path 二分答案 [JSOI 2008] 火星人 对于第一个操作用\(hash + 二分\)来求 ...

  2. System.Collections.IDictionary.cs

    ylbtech-System.Collections.IDictionary.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKe ...

  3. F - GCD - Extreme (II) UVA - 11426

    Given the value of N, you will have to find the value of G. The definition of G is given below:

  4. php array_unshift,array_push追加数组元素

    追加元素在数组前面:<?php $a=array("a"=>"Cat","b"=>"Dog"); ar ...

  5. Requests+Excel接口自动化测试(Python)

    一.框架结构:  工程目录 二.Case文件设计 三.基础包 base 3.1 封装get/post请求(runmethon.py) import requests import json class ...

  6. MVVM test

    示例代码 public class RegisterUserViewModel { public UserInfo userInfo { get; set; } public ICommand Cli ...

  7. 0901NOIP模拟测试赛后总结

    突然想学迪哥列一下分数线搞清楚自己和别人的差距. rank1- 5- 6-分. 差距很大啊.尤其是和某kyh.大家都开玩笑说天皇是个变态.但是事实摆在这儿,同样坐在机房这么长的时间,人家又AK了. 我 ...

  8. vue-resourse简单使用方法

    一.安装引用 安装: npm install vue-resource --save-dev 引用: /*引入Vue框架*/ import Vue from 'vue' /*引入资源请求插件*/ im ...

  9. centos 7 安装dotnet core

    dotnetcore 支持的Linux 版本请看官网:https://docs.microsoft.com/zh-cn/dotnet/core/linux-prerequisites?tabs=net ...

  10. 我的服装DRP之即时通讯——为WCF增加UDP绑定(应用篇)

    发个牢骚,博客园发博文竟然不能写副标题.这篇既为我的服装DRP系列第二篇,也给为WCF增加UDP绑定系列收个尾.原本我打算记录开发过程中遇到的一些问题和个人见解,不过写到一半发现要写的东西实在太多,有 ...