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存储时间出现不一致的问题
Apr 28 MySQL
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 MySQL
MySQL 8.0 Online DDL快速加列的相关总结
Jun 02 MySQL
浅谈MySQL next-key lock 加锁范围
Jun 07 MySQL
MySQL中存储时间的最佳实践指南
Jul 01 MySQL
mysql 数据插入优化方法之concurrent_insert
Jul 01 MySQL
mysql备份策略的实现(全量备份+增量备份)
Jul 07 MySQL
MySQL的全局锁和表级锁的具体使用
Aug 23 MySQL
mysql中整数数据类型tinyint详解
Dec 06 MySQL
mysql的Buffer Pool存储及原理
Apr 02 MySQL
MySQL的存储函数与存储过程的区别解析
Apr 08 MySQL
Mysql表数据比较大情况下修改添加字段的方法实例
Jun 28 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文件操作的详细诠释
2013/06/21 PHP
android上传图片到PHP的过程详解
2015/08/03 PHP
如何使用php脚本给html中引用的js和css路径打上版本号
2015/11/18 PHP
使用正则替换变量
2007/05/05 Javascript
javascript arguments 传递给函数的隐含参数
2009/08/21 Javascript
js 自定义的联动下拉框
2010/02/07 Javascript
javascript 类型判断代码分析
2010/03/28 Javascript
Ext JS 4官方文档之三 -- 类体系概述与实践
2012/12/16 Javascript
使用phantomjs进行网页抓取的实现代码
2014/09/29 Javascript
js实现iframe自动自适应高度的方法
2015/02/17 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
介绍JavaScript的一个微型模版
2015/06/24 Javascript
jquery原理以及学习技巧介绍
2015/11/11 Javascript
JS密码生成与强度检测完整实例(附demo源码下载)
2016/04/06 Javascript
jQuery实现下拉框功能实例代码
2016/05/06 Javascript
JavaScript基础进阶之数组方法总结(推荐)
2017/09/04 Javascript
详解使用PM2管理nodejs进程
2017/10/24 NodeJs
如何使用webpack打包一个库library的方法步骤
2019/12/18 Javascript
Python探索之自定义实现线程池
2017/10/27 Python
利用python循环创建多个文件的方法
2018/10/25 Python
浅谈keras的深度模型训练过程及结果记录方式
2020/01/24 Python
简单了解如何封装自己的Python包
2020/07/08 Python
Python logging日志库空间不足问题解决
2020/09/14 Python
时尚设计师手表:The Watch Cabin
2018/10/06 全球购物
MIXIT官网:俄罗斯最大的化妆品公司之一
2020/01/25 全球购物
介绍Java的内部类
2012/10/27 面试题
医药类个人求职的自我评价
2014/02/12 职场文书
物业管理毕业生的自我评价
2014/02/17 职场文书
公共场所禁烟倡议书
2014/08/30 职场文书
公司授权委托书范本
2014/09/18 职场文书
三方股东合作协议书
2014/10/28 职场文书
骨干教师申报材料
2014/12/17 职场文书
2015年数学教研工作总结
2015/07/22 职场文书
2015年小学语文教师工作总结
2015/10/23 职场文书
Python+Appium新手教程
2021/04/17 Python
铁拳制作人赞《铁拳7》老头环Mod:制作精良 但别弄了
2022/04/03 其他游戏