MySQL数据库(25):外键 foreing key

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL数据库(25):外键 foreing key

外键 foreing key

外键表示了两个实体之间的联系

外键 foreing key: A表中的一个字段的值指向另B表的主键

  • B: 主表
  • A: 从表
主表:主键(主关键字) = 从表:外键(外关键字)

1、外键操作

1.1、增加外键

基本语法

方式一:创建表的时候增加外键

[constraint `外键名`] foreign key (外键字段) references 主表(主键);

方式二:创建表后增加外键

alter table 从表 add [constraint `外关键字`] foreign key (外键字段) references 主表(主键);
• 1

示例1: 创建表的时候增加外键

-- 创建外键
create table my_foreign(
    id int primary key auto_increment,
    name varchar(10) not null,
    class_id int,
    -- 创建时,会自动增加普通索引
    foreign key (class_id) references my_class(id)
);
mysql> show create table my_foreign;
CREATE TABLE `my_foreign` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci NOT NULL,
  `class_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `class_id` (`class_id`),
  CONSTRAINT `my_foreign_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `my_class` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
mysql> desc my_foreign;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| name     | varchar(10) | NO   |     | NULL    |                |
| class_id | int(11)     | YES  | MUL | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

MUL多索引 外键本身也是索引

示例2: 创建表后增加外键

-- 查看原来的表
mysql> desc my_class;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| name  | varchar(10) | NO   | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
mysql> show create table my_class;
CREATE TABLE `my_class` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
mysql> desc my_student;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| name     | varchar(10) | YES  |     | NULL    |                |
| class_id | int(11)     | YES  |     | NULL    |                |
| age      | int(11)     | YES  |     | NULL    |                |
| gender   | int(11)     | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
mysql> show create table my_student\G
*************************** 1. row ***************************
       Table: my_student
Create Table: CREATE TABLE `my_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
-- 增加外键
alter table my_student add constraint fk_class_id foreign key (class_id) references my_class(id);
mysql> show create table my_student\G
*************************** 1. row ***************************
       Table: my_student
Create Table: CREATE TABLE `my_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_class_id` (`class_id`),
  CONSTRAINT `fk_class_id` FOREIGN KEY (`class_id`) REFERENCES `my_class` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

1.2、删除外键

外键不允许修改,只能先删除再添加

alter table 从表 drop foreign key 外键名字;
• 1

示例

alter table my_student drop foreign key `fk_class_id`;
mysql> show create table my_student\G
*************************** 1. row ***************************
       Table: my_student
Create Table: CREATE TABLE `my_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_class_id` (`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

外键不会删除普通索引,只会删除外键

删除普通索引

alter table 表名 drop index 索引名字;
• 1

1.3、外键的基本要求

  1. 外键字段需要与关联的主表的主关键字段类型完全一致
  2. 基本属性也要相同
  3. 如果是表后增加外键,对数据还有一定的要求(从表数据与主表的关联关系)
  4. 外键只能使用innodb存储引擎,myisam不支持

2、外键约束

外键约束:通过建立外键关系后,对主表和从表都会有一定的数据约束效律


2.1、约束的基本概念

当外键产生时,外键所在的表(从表)会受制于主表数据的存在,从而导致数据不能进行某些不符合规范的操作

不能插入主表不存在的数据


如果一张表被其他表外键引入,那么该表的数据操作不能随意,必须保证从表数据的有效性,不能随意删除一个被从表引入的记录

mysql> select * from my_class;
+----+--------+
| id | name   |
+----+--------+
|  1 | 一班   |
|  3 | 三班   |
|  2 | 二班   |
+----+--------+
insert into my_foreign (name, class_id) values ('张飞', 1);
Query OK, 1 row affected (0.01 sec)
-- 主表没有id=4的记录,从表不能插入该数据
insert into my_foreign (name, class_id) values ('张飞', 4);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mydatabase`.`my_foreign`, CONSTRAINT `my_foreign_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `my_class` (`id`))
mysql> select * from my_foreign;
+----+--------+----------+
| id | name   | class_id |
+----+--------+----------+
|  1 | 张飞   |        1 |
+----+--------+----------+
1 row in set (0.00 sec)
-- 从表中引用了id=1的记录,该数据不能被删除
delete from my_class where id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`mydatabase`.`my_foreign`, CONSTRAINT `my_foreign_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `my_class` (`id`))

2.2、外键约束的概念

基本语法

add foreign key (外键字段) references 主表(主键) on 约束模式;
• 1

约束模式有三种

district 严格模式 默认,不允许操作

cascade 级联模式,一起操作,主表变化,从表的数据也跟着变化

set null 置空模式 主表变化(删除),从表对应记录设置,前提是从表中对应的外键字段允许为空

外键约束的主要对象是主表操作,从表就是不能插入主表不存在的数据


通常在进行约束的时候,需要制定操作,update 和 delete

常用的模式

-- 更新级联, 删除置空, 空格隔开
on update cascade on delete set null;
-- 增加约束模式
alter table my_student
add foreign key (class_id) references my_class(id)
on update cascade on delete set null;
mysql> show create table my_student\G
*************************** 1. row ***************************
       Table: my_student
Create Table: CREATE TABLE `my_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `gender` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `class_id` (`class_id`),
  CONSTRAINT `my_student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `my_class` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
mysql> select * from my_class;
+----+--------+
| id | name   |
+----+--------+
|  1 | 一班   |
|  3 | 三班   |
|  2 | 二班   |
+----+--------+
3 rows in set (0.00 sec)
mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        2 |   20 |      2 |
|  4 | 张飞   |        2 |   21 |      1 |
|  5 | 关羽   |     NULL |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+
6 rows in set (0.00 sec)
-- 更新主表
update my_class set id = 4 where id = 2;
-- 从表中所有class_id=2 的记录被修改为了 class_id=4
mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |        4 |   20 |      2 |
|  4 | 张飞   |        4 |   21 |      1 |
|  5 | 关羽   |     NULL |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+
-- 删除主表数据
delete from  my_class where id = 4;
-- 从表中记录class_id=4被修改为class_id=null;
mysql> select * from my_student;
+----+--------+----------+------+--------+
| id | name   | class_id | age  | gender |
+----+--------+----------+------+--------+
|  1 | 刘备   |        1 |   18 |      2 |
|  2 | 李四   |        1 |   19 |      1 |
|  3 | 王五   |     NULL |   20 |      2 |
|  4 | 张飞   |     NULL |   21 |      1 |
|  5 | 关羽   |     NULL |   22 |      2 |
|  6 | 曹操   |        1 |   20 |   NULL |
+----+--------+----------+------+--------+
6 rows in set (0.00 sec)

2.3、约束的作用

保证数据的完整性,主表与从表的数据要一致

正是因为外键有非常强大的数据约束作用,而且可能导致数据再后台变化的不可控性,导致程序在设计开发逻辑的时候,没有办法很好的把握数据,所以外键很少使用

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
关系型数据库 MySQL
MYSQL-多表操作-外键约束
MYSQL-多表操作-外键约束
|
6月前
|
关系型数据库 MySQL 程序员
老程序员分享:MYSQL外键(ForeignKey)的使用
老程序员分享:MYSQL外键(ForeignKey)的使用
67 0
|
2月前
|
Ubuntu 关系型数据库 MySQL
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
ubuntu使用aliyun源+mysql删除有外键约束的数据+查看特定目录的大小
87 4
|
3月前
|
SQL 关系型数据库 MySQL
MySQL中外键的使用及外键约束策略
这篇文章讨论了MySQL中使用外键的重要性,包括外键的概念、不使用外键可能导致的问题、如何设置外键约束以及不同的外键约束策略(如CASCADE和SET NULL),并通过示例演示了这些概念。
MySQL中外键的使用及外键约束策略
|
3月前
|
关系型数据库 MySQL 测试技术
MySQL外键使用的考量与建议
综上所述,虽然MySQL的外键提供了一种强大的工具来维护数据之间的一致性和完整性,但在决定是否使用外键时,需要权衡其带来的好处和潜在的性能影响。通过仔细的规划和测试,可以最大化地利用外键的优势,同时避免一些常见的陷阱。
43 3
|
3月前
|
关系型数据库 MySQL 测试技术
MySQL外键使用的考量与建议
综上所述,虽然MySQL的外键提供了一种强大的工具来维护数据之间的一致性和完整性,但在决定是否使用外键时,需要权衡其带来的好处和潜在的性能影响。通过仔细的规划和测试,可以最大化地利用外键的优势,同时避免一些常见的陷阱。
185 1
|
3月前
|
数据库 Python
django中数据库外键可以自定义名称吗
django中数据库外键可以自定义名称吗
|
5月前
|
关系型数据库 MySQL 数据库
Mysqlbug-Could not create or access the registry key needed for the MySQL applicationto, TIMESTAMP w
Mysqlbug-Could not create or access the registry key needed for the MySQL applicationto, TIMESTAMP w
|
6月前
|
SQL 关系型数据库 MySQL
MySQL外键约束行为解析:CASCADE, NO ACTION, RESTRICT, SET NULL
MySQL外键约束行为解析:CASCADE, NO ACTION, RESTRICT, SET NULL
537 0
|
7月前
|
关系型数据库 MySQL Linux
【MySQL-9】一文带你搞定 外键约束&其【更新/删除行为】(可cv代码&案例演示)
【MySQL-9】一文带你搞定 外键约束&其【更新/删除行为】(可cv代码&案例演示)