返回顶部
首页 > 资讯 > 数据库 >MySQL外键约束的实例讲解
  • 472
分享到

MySQL外键约束的实例讲解

MySQL外键约束 2022-05-12 07:05:38 472人浏览 泡泡鱼
摘要

 Mysql的外键约束是用来在两个表之间建立链接的,其中一个表发生变化,另外一个表也发生变化。从这个特点来看,它主要是为了保证表数据的一致性和完整性的。 对于两个通过外键关联的表,相关联字段中主键所在的表是

 Mysql的外键约束是用来在两个表之间建立链接的,其中一个表发生变化,另外一个表也发生变化。从这个特点来看,它主要是为了保证表数据的一致性和完整性的。
对于两个通过外键关联的表,相关联字段中主键所在的表是主表,也称之为父表,外键所在的表是从表,也称之为子表,定义外键的时候需要遵守几个规则:

父表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照。
2、必须为父表定义主键。
3、主键不能包含空值,但允许在外键中出现空值。也就是说,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
4、外键中列的数目必须和父表的主键中列的数目相同。
5、外键中列的数据类型必须和父表主键中对应列的数据类型相同。说这么多比较笼统,还是看看例子吧。


mysql:yeyztest ::>>create table fk_test_1( 
 -> id int not null primary key auto_increment,
 -> name varchar() default '');
Query OK, rows affected (0.10 sec)

mysql:yeyztest ::>>create table fk_test_2(
 -> id int not null primary key auto_increment,
 -> uid int, 
 -> foreign key fk_uid(uid) references fk_test_1(id));
Query OK, rows affected (0.06 sec)

  这里我们创建两个表,一个是fk_test_1,一个是fk_test_2,其中fk_test_2的uid列上设置外键,关联fk_test_1的表的id列,这里很明显,fk_test_1是父表,而fk_test_2是子表,接下来我们进行数据插入实验。


mysql:yeyztest ::>>insert into fk_test_1 values (,'aaa'),(,'bbb');
Query OK, rows affected (0.00 sec)
Records: Duplicates: Warnings: 

mysql:yeyztest ::>>select * from fk_test_1;
+----+------+
| id | name |
+----+------+
| | aaa |
| | bbb |
+----+------+
 rows in set (0.00 sec)

mysql:yeyztest ::>>insert into fk_test_2 values (,),(,);
Query OK, rows affected (0.00 sec)
Records: Duplicates: Warnings: 

mysql:yeyztest ::>>insert into fk_test_2 values (,);
Query OK, row affected (0.00 sec)


mysql:yeyztest ::>>insert into fk_test_2 values (,);  
ERROR (): Cannot add or update a child row: a foreign key constraint fails (`yeyztest`.`fk_test_2`, CONSTRAINT `fk_test_2_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `fk_test_1` (`id`))

    先在主表上插入两条数据,分别是id=1和id=2的数据,然后再子表插入数据,子表插入uid=1和uid=2的数据都能成功,而要插入uid=3的数据时提示失败,也就是说,默认情况下,子表进行插入时,插入的外键关联字段值必须是父表被关联的列包含的值。注意这里的默认情况,后续会进行说明。

   再来看看删除的情况,


mysql:yeyztest ::>>select * from fk_test_2 ;
+----+------+
| id | uid |
+----+------+
| |  |
| |  |
| |  |
+----+------+
 rows in set (0.00 sec)

mysql:yeyztest ::>>delete from fk_test_2 where id=;
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>select * from fk_test_1 ;  
+----+------+
| id | name |
+----+------+
| | aaa |
| | bbb |
+----+------+
 rows in set (0.00 sec)

mysql:yeyztest ::>>delete from fk_test_1 where id=; 
ERROR (): Cannot delete or update a parent row: a foreign key constraint fails (`yeyztest`.`fk_test_2`, CONSTRAINT `fk_test_2_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `fk_test_1` (`id`))

   可以看到,在子表fk_test_2上进行删除,没有出现任何问题,而在父表fk_test_1上删除时,显示无法删除id=1的值,原因是有一个外键约束存在,也就是说,默认情况下,在父表进行删除时,无法直接删除子表中已经存在依赖关联的列值。注意这里的默认情况,下面将会说明。

    既然delete不成功,试试update,


mysql:yeyztest ::>>update fk_test_1 set id= where id=;   
ERROR (): Cannot delete or update a parent row: 
a foreign key constraint fails (`yeyztest`.`fk_test_2`, 
CONSTRAINT `fk_test_2_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `fk_test_1` (`id`))

mysql:yeyztest ::>>update fk_test_1 set name='ccc' where id=; 
Query OK, row affected (0.00 sec)
Rows matched: Changed: Warnings: 

     可以看到,update父表的主键列还是不能成功执行,但是update其他的列,可以成功执行。

    到这里,我们已经知道,外键的存在是为了保证数据的完整和统一性,但是也带来了一点问题,那就是父表中凡是被子表依赖的列,都没办法删除了,这不是我们想要的,有一些数据确实会过期,我们有删除的需求,那么这个时候应该怎么办?

    在上面的测试中,我们反复提到一个词,就是默认情况,我们没有设置外键的删除和更新规则,这里mysql帮我们使用了最严格的的规则,那就是restrict,其实还有其他一些规则,这里全部列出来:

  • delete父表的情况:

cascade,set null,no action,restrict

  • update父表的情况:

cascade,set null,no action,restrict

   其中

  • restrict是默认操作,它表示拒绝父表删除或者修改外键已经被子表所依赖的列,这是最安全的设置;
  • cascade表示在父表发生删除的时候直接删除子表的记录,这是最危险的设置;
  • set null表示父表删除的时候,对子表进行null值处理;
  • no action表示父表删除的时候,子表不进行任何改动。

   设置关联的语法如下:


alter table 表名 add constraint FK_ID foreign key (外键字段名) references 外表表名 (主键字段名)
[on delete {cascade | set null | no action| restrict}]
[on update {cascade | set null | no action| restrict}]

   现在我们测试一下这其他三种情况,首先看cascade的情况:


mysql:yeyztest ::>>select * from fk_test_1;
+----+------+
| id | name |
+----+------+
| | ccc |
| | bbb |
+----+------+
 rows in set (0.00 sec)

mysql:yeyztest ::>>select * from fk_test_2;
+----+------+
| id | uid |
+----+------+
| |  |
| |  |
+----+------+
 rows in set (0.00 sec)

mysql:yeyztest ::>>show create table fk_test_2\G
*************************** 1. row ***************************
  Table: fk_test_2
Create Table: CREATE TABLE `fk_test_2` (
 `id` int() NOT NULL AUTO_INCREMENT,
 `uid` int() DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `fk_uid` (`uid`),
 CONSTRAINT `fk_test_2_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `fk_test_1` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8
 row in set (0.00 sec)

mysql:yeyztest ::>>alter table fk_test_2 drop foreign key fk_test_2_ibfk_1;
Query OK, rows affected (0.02 sec)
Records: Duplicates: Warnings: 

mysql:yeyztest ::>>alter table fk_test_2 add constraint fk_uid foreign key (uid) references fk_test_1(id) on delete cascade;
Query OK, rows affected (0.03 sec)
Records: Duplicates: Warnings: 

#######################################
####此处删除父表id=的记录,查看子表的结果###
#######################################
mysql:yeyztest ::>>delete from fk_test_1 where id=;
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>select * from fk_test_1 ;
+----+------+
| id | name |
+----+------+
| | ccc |
+----+------+
 row in set (0.00 sec)

mysql:yeyztest ::>>select * from fk_test_2 ;
+----+------+
| id | uid |
+----+------+
| |  |
+----+------+
 row in set (0.00 sec)

   可以看到,一开始,父表的值包含id=1和id=2的值,子表的值包含uid=2和uid=1的值,当我们删除父表的id=2的值之后,子表中uid=2的值也直接被删除了。这就是cascade的作用,也就是级联删除。

在看一眼set null的情况:


mysql:yeyztest ::>>alter table fk_test_2 drop foreign key fk_uid;   
Query OK, row affected (0.02 sec)
Records: Duplicates: Warnings: 

mysql:yeyztest ::>>alter table fk_test_2 add CONSTRAINT `fk_uid` FOREIGN KEY (`uid`) REFERENCES `fk_test_1` (`id`) ON DELETE set null;
Query OK, row affected (0.03 sec)
Records: Duplicates: Warnings: 

mysql:yeyztest ::>>delete from fk_test_1 where id=;
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>select *from fk_test_1 ;
Empty set (0.00 sec)

mysql:yeyztest ::>>select *from fk_test_2 ;
+----+------+
| id | uid |
+----+------+
| | NULL |
+----+------+
 row in set (0.00 sec)

   可以看到,设置了set null之后,当父表删除id=1的值时,子表的uid的值变成了null,而没有删除记录。

no action的情况也是类似,只不过是子表的记录没有发生任何改动。

    以上是父表进行delete的操作,当父表进行update的时候,子表可以选择的情况也有以上四种,和delete基本保持一致,这里不再赘述。有兴趣可以自己测试一发。

   最后,说明一点,子表的外键列可以为空值。


mysql:yeyztest ::>>insert into fk_test_1 values (,);
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>select *from fk_test_2 ;   
+----+------+
| id | uid |
+----+------+
| | NULL |
+----+------+
 row in set (0.00 sec)

mysql:yeyztest ::>>insert into fk_test_2 values (,NULL);
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>insert into fk_test_2 values (,NULL);
Query OK, row affected (0.00 sec)

mysql:yeyztest ::>>select * from fk_test_2;
+----+------+
| id | uid |
+----+------+
| | NULL |
| | NULL |
| | NULL |
+----+------+
 rows in set (0.00 sec)

以上就是MySQL外键约束的实例讲解的详细内容,更多关于MySQL外键约束的资料请关注自学编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL外键约束的实例讲解

本文链接: https://lsjlt.com/news/9934.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL外键约束的实例讲解
     MySQL的外键约束是用来在两个表之间建立链接的,其中一个表发生变化,另外一个表也发生变化。从这个特点来看,它主要是为了保证表数据的一致性和完整性的。 对于两个通过外键关联的表,相关联字段中主键所在的表是...
    99+
    2022-05-12
    MySQL 外键约束
  • MySQL外键约束(FOREIGN KEY)案例讲解
    MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。 外键用来建立主表与从表...
    99+
    2022-05-27
    MySQL外键约束 MySQL FOREIGN KEY讲解
  • MySQL主键约束和外键约束详解
    目录1、PRIMARY KEY2、FOREIGN KEY3、表的设计3.1 一对一3.2 一对多3.3 多对多1、PRIMARY KEY 上期我们讲述了 not null 和 unique 约束,而本期的第一个约束就是这...
    99+
    2023-03-13
    mysql主键约束和外键约束 mysql主键和外键
  • 【MySQL】主键约束和外键约束
    目录 1、PRIMARY KEY 2、FOREIGN KEY 3、表的设计 3.1 一对一 3.2 一对多 3.3 多对多 1、PRIMARY KEY 上期我们讲述了 not null 和 unique 约束,而本期的第一个约束就...
    99+
    2023-09-01
    mysql 数据库
  • MySQL外键约束
    CASCADE:父表delete、update的时候,子表会delete、update掉关联记录; SET NULL:父表delete、update的时候,子表会将关联记录的外键字段所在列设为null,所以注意在设计子表时外键不能设为no...
    99+
    2020-02-25
    MySQL外键约束
  • 详解MySQL 外键约束
    官方文档: https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html 1.外键作用: MySQL通过外键约束来保证表与表之间的数...
    99+
    2022-05-11
    MySQL 外键 MySQL 外键约束
  • MySQL外键约束详解
    目录一、mysql外键约束作用二、外键约束创建(一)创建外键约束的条件(二)在创建数据表时创建外键约束(三)在创建数据表后添加外键约束三、外键约束功能演示今天继续给大家介绍MySQL相关知识,本文主要内容是MySQL外键...
    99+
    2022-07-29
    Mysql外键约束
  • MySQL外键约束(Foreign Key)案例详解
    目录一、mysql外键约束作用二、外键约束创建(一)创建外键约束的条件(二)在创建数据表时创建外键约束(三)在创建数据表后添加外键约束三、外键约束功能演示总结今天继续给大家介绍MySQL相关知识,本文主要内容是MySQL...
    99+
    2022-06-28
    mysql外键约束怎么写 mysql创建外键约束的语法 mysql创建表时添加外键约束
  • MySQL主键约束和外键约束怎么设置
    这篇“MySQL主键约束和外键约束怎么设置”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“M...
    99+
    2023-03-13
    mysql
  • 【⑫MySQL | 约束(二)】外键 | 默认值 | 检查约束 — 综合案例
    前言 ✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL外键 | 默认值 | 检查约束 以及综合案例的分享✨ 目录 前言6. 外键约束(FOREIGN KEY,FK)7. 默认值约束和检查约束8. 综合实战总结 ...
    99+
    2023-08-21
    mysql 数据库 sql
  • mysql如何实现主外键约束
    这篇文章将为大家详细讲解有关mysql如何实现主外键约束,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。mysql主键约束的写法:“CREATE TABLE 表名(字段名 ...
    99+
    2024-04-02
  • 怎么写mysql外键约束
    今天就跟大家聊聊有关怎么写mysql外键约束,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。mysql外键约束的写法:【[CONSTRAINT <...
    99+
    2024-04-02
  • mysql怎么加外键约束
    如何使用 mysql 添加外键约束?确定主外键字段。在子表中定义外键约束,引用主表的主键字段。语法:alter table 子表_名称 add foreign key (外键_字段) r...
    99+
    2024-05-30
    mysql
  • MySQL数据库中的外键约束详解
    外键是关系数据库中一种重要的数据完整性约束,它用于建立表与表之间的关联关系。外键约束指定了一个表的列或一组列必须存在于另一个表的主键...
    99+
    2023-09-22
    MySQL
  • 补12.关于mysql的外键约束
    一、什么是mysql中的外键(froeign key)假如说有两张表,其中一张表的某个字段指向了另一张表的主键,这就可以称之为外键(froeign key)。在子表中增加一条记录时,需要确定是否有与父表相对...
    99+
    2024-04-02
  • mysql取消外键约束的方法
    这篇文章主要介绍了mysql取消外键约束的方法,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。mysql取消外键限制(约束)的方法:通过“ALTE...
    99+
    2024-04-02
  • MySQL设置外键约束的方法
    这篇文章给大家分享的是有关MySQL设置外键约束的方法的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。MySQL 外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接,...
    99+
    2024-04-02
  • mysql如何建立外键约束
    小编给大家分享一下mysql如何建立外键约束,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!mysql建立外键约束的方法:直接执行【CREATE TABLE stu(sid INT PRIMAR...
    99+
    2024-04-02
  • mysql如何增加外键约束
    小编给大家分享一下mysql如何增加外键约束,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! mysql中可用“ALTER TABLE”语句和“FOREIGN K...
    99+
    2024-04-02
  • mysql如何查询外键约束
    这篇文章主要介绍了mysql如何查询外键约束的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇mysql如何查询外键约束文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作