MySQL外键约束(FOREIGN KEY)案例讲解


Posted in MySQL onAugust 23, 2021

MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。

外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。比如,一个水果摊,只有苹果、桃子、李子、西瓜等 4 种水果,那么,你来到水果摊要买水果就只能选择苹果、桃子、李子和西瓜,其它的水果都是不能购买的。

主表删除某条记录时,从表中与之对应的记录也必须有相应的改变。一个表可以有一个或多个外键,外键可以为空值,若不为空值,则每一个外键的值必须等于主表中主键的某个值。

定义外键时,需要遵守下列规则:

  • 主表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则主表与从表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。
  • 必须为主表定义主键。
  • 主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
  • 在主表的表名后面指定列名或列名的组合。这个列或列的组合必须是主表的主键或候选键。
  • 外键中列的数目必须和主表的主键中列的数目相同。
  • 外键中列的数据类型必须和主表主键中对应列的数据类型相同。

在创建表时设置外键约束

在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键,具体的语法格式如下:

[CONSTRAINT <外键名>] FOREIGN KEY 字段名 [,字段名2,…]
REFERENCES <主表名> 主键列1 [,主键列2,…]

例 1

为了展现表与表之间的外键关系,本例在 test_db 数据库中创建一个部门表 tb_dept1,表结构如下表所示。

字段名称 数据类型 备注
id INT(11) 部门编号
name VARCHAR(22) 部门名称
location VARCHAR(22) 部门位置

创建 tb_dept1 的 SQL 语句和运行结果如下所示。

mysql> CREATE TABLE tb_dept1
    -> (
    -> id INT(11) PRIMARY KEY,
    -> name VARCHAR(22) NOT NULL,
    -> location VARCHAR(50)
    -> );
Query OK, 0 rows affected (0.37 sec)

创建数据表 tb_emp6,并在表 tb_emp6 上创建外键约束,让它的键 deptId 作为外键关联到表 tb_dept1 的主键 id,SQL 语句和运行结果如下所示。

mysql> CREATE TABLE tb_emp6
    -> (
    -> id INT(11) PRIMARY KEY,
    -> name VARCHAR(25),
    -> deptId INT(11),
    -> salary FLOAT,
    -> CONSTRAINT fk_emp_dept1
    -> FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
    -> );
Query OK, 0 rows affected (0.37 sec)

mysql> DESC tb_emp6;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id     | int(11)     | NO   | PRI | NULL    |       |
| name   | varchar(25) | YES  |     | NULL    |       |
| deptId | int(11)     | YES  | MUL | NULL    |       |
| salary | float       | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
4 rows in set (1.33 sec)

以上语句执行成功之后,在表 tb_emp6 上添加了名称为 fk_emp_dept1 的外键约束,外键名称为 deptId,其依赖于表 tb_dept1 的主键 id。

注意:从表的外键关联的必须是主表的主键,且主键和外键的数据类型必须一致。例如,两者都是 INT 类型,或者都是 CHAR 类型。如果不满足这样的要求,在创建从表时,就会出现“ERROR 1005(HY000): Can't create table”错误。

在修改表时添加外键约束

外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或者是没有数据。

在修改数据表时添加外键约束的语法格式如下:

ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>
FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);

例 2

修改数据表 tb_emp2,将字段 deptId 设置为外键,与数据表 tb_dept1 的主键 id 进行关联,SQL 语句和运行结果如下所示。

mysql> ALTER TABLE tb_emp2
    -> ADD CONSTRAINT fk_tb_dept1
    -> FOREIGN KEY(deptId)
    -> REFERENCES tb_dept1(id);
Query OK, 0 rows affected (1.38 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE tb_emp2\G
*************************** 1. row ***************************
       Table: tb_emp2
Create Table: CREATE TABLE `tb_emp2` (
  `id` int(11) NOT NULL,
  `name` varchar(30) DEFAULT NULL,
  `deptId` int(11) DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_tb_dept1` (`deptId`),
  CONSTRAINT `fk_tb_dept1` FOREIGN KEY (`deptId`) REFERENCES `tb_dept1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF-8
1 row in set (0.12 sec)

注意:在为已经创建好的数据表添加外键约束时,要确保添加外键约束的列的值全部来源于主键列,并且外键列不能为空。

删除外键约束

当一个表中不需要外键约束时,就需要从表中将其删除。外键一旦删除,就会解除主表和从表间的关联关系。

删除外键约束的语法格式如下所示:

ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;

例 3

删除数据表 tb_emp2 中的外键约束 fk_tb_dept1,SQL 语句和运行结果如下所示。

mysql> ALTER TABLE tb_emp2
    -> DROP FOREIGN KEY fk_tb_dept1;
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE tb_emp2\G
*************************** 1. row ***************************
       Table: tb_emp2
Create Table: CREATE TABLE `tb_emp2` (
  `id` int(11) NOT NULL,
  `name` varchar(30) DEFAULT NULL,
  `deptId` int(11) DEFAULT NULL,
  `salary` float DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_tb_dept1` (`deptId`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF-8
1 row in set (0.00 sec)

可以看到,tb_emp2 中已经不存在 FOREIGN KEY,原有的名称为 fk_emp_dept 的外键约束删除成功。

到此这篇关于MySQL外键约束(FOREIGN KEY)案例讲解的文章就介绍到这了,更多相关MySQL外键约束(FOREIGN KEY)内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL 使用SQL语句修改表名的实现
Apr 07 MySQL
MySQL优化之如何写出高质量sql语句
May 17 MySQL
Mysql数据库按时间点恢复实战记录
Jun 30 MySQL
MySQL系列之四 SQL语法
Jul 02 MySQL
MySQL里面的子查询的基本使用
Aug 02 MySQL
一文带你探究MySQL中的NULL
Nov 11 MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 MySQL
MySQL实战记录之如何快速定位慢SQL
Mar 23 MySQL
MySQL创建管理KEY分区
Apr 13 MySQL
MySQL数据库之内置函数和自定义函数 function
Jun 16 MySQL
MySQL性能指标TPS+QPS+IOPS压测
Aug 05 MySQL
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
Dec 24 MySQL
MySQL 1130异常,无法远程登录解决方案详解
Aug 23 #MySQL
Node-Red实现MySQL数据库连接的方法
Aug 07 #MySQL
MySQL如何解决幻读问题
Aug 07 #MySQL
浅谈MySQL之select优化方案
Aug 07 #MySQL
SQL实现LeetCode(197.上升温度)
Aug 07 #MySQL
SQL实现LeetCode(196.删除重复邮箱)
Aug 07 #MySQL
MySQL Shell import_table数据导入的实现
Aug 07 #MySQL
You might like
PHP开发环境配置(MySQL数据库安装图文教程)
2010/04/28 PHP
php返回相对时间(如:20分钟前,3天前)的方法
2015/04/14 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
php+webSoket实现聊天室示例代码(附源码)
2017/02/17 PHP
thinkPHP5框架自定义验证器实现方法分析
2018/06/11 PHP
jquery tools 系列 scrollable学习
2009/09/06 Javascript
jQuery使用数组编写图片无缝向左滚动
2012/12/11 Javascript
ExtJS判断IE浏览器类型的方法
2014/02/10 Javascript
require.js的用法详解
2015/10/20 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
2016/10/13 Javascript
bootstrap选项卡使用方法解析
2017/01/11 Javascript
Vue中fragment.js使用方法详解
2017/03/09 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
微信小程序中换行空格(多个空格)写法详解
2018/07/10 Javascript
vue中将html字符串转换成html后遇到的问题小结
2018/12/10 Javascript
JavaScript中的this/call/apply/bind的使用及区别
2020/03/06 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
python基础教程之对象和类的实际运用
2014/08/29 Python
Python实现的飞速中文网小说下载脚本
2015/04/23 Python
python基于itchat实现微信群消息同步机器人
2017/02/27 Python
Python实现随机选择元素功能
2017/09/14 Python
Numpy中转置transpose、T和swapaxes的实例讲解
2018/04/17 Python
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
Django csrf 两种方法设置form的实例
2019/02/03 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
Original Penguin美国官网:布拉德皮特、强尼德普喜爱的服装品牌
2016/10/25 全球购物
美国领先的家居装饰和礼品商店:Kirkland’s
2017/01/30 全球购物
BudgetAir印度:预订航班、酒店和汽车租赁
2019/07/07 全球购物
巴西购物网站:Submarino
2020/01/19 全球购物
Kingsoft金山公司C/C++笔试题
2016/05/10 面试题
喝酒检查书范文
2014/02/23 职场文书
治超工作实施方案
2014/05/04 职场文书
世界遗产的导游词
2015/02/13 职场文书