zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

MySql---外键复习

mysql --- 复习 外键
2023-09-14 09:13:35 时间


MySQL外键约束(FOREIGN KEY)

  • MySQL 外键约束(FOREIGN KEY)用来在两个表的数据之间建立链接,它可以是一列或者多列。一个表可以有一个或多个外键。
  • 外键对应的是参照完整性,一个表的外键可以为空值,若不为空值,则每一个外键的值必须等于另一个表中主键的某个值。
  • 外键是表的一个字段,不是本表的主键,但对应另一个表的主键。定义外键后,不允许删除另一个表中具有关联关系的行。
  • 外键的主要作用是保持数据的一致性、完整性。例如,部门表 tb_dept 的主键是 id,在员工表 tb_emp5 中有一个键 deptId 与这个 id 关联。

主表和从表

  • 主表(父表):对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表。
  • 从表(子表):对于两个具有关联关系的表而言,相关联字段中外键所在的表就是从表。

选取设置 MySQL 外键约束的字段

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

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

在创建表时设置外键约束

在数据表中创建外键使用 FOREIGN KEY 关键字,具体的语法规则如下:

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

其中:外键名为定义的外键约束的名称,一个表中不能有相同名称的外键;字段名表示子表被外健约束的字段名;主表名即被子表外键所依赖的表的名称;主键列表示主表中定义的主键列或者列组合。


部门和员工案例演示

创建父表和从表

USE test1;
#部门表--父表先创建
#主表: 可以约束其他表的字段值的表
CREATE TABLE depart(
 id INT(4) PRIMARY KEY AUTO_INCREMENT,
 d_name VARCHAR(10)
);

#员工表(从表) :被约束的表,外键写在从表里面
CREATE TABLE emp(
id INT(4) PRIMARY KEY AUTO_INCREMENT,
e_name VARCHAR(10),
d_id INT(4),#这里外键列的类型要和主表的主键类型一致
#写外键约束
#定义了一个emp_dept_fk名字的外键,本表中d_id字段为外键,被参考表dept的id字段所约束
CONSTRAINT emp_dept_fk FOREIGN KEY(d_id) REFERENCES depart(id) 
);

父表插入数据

INSERT INTO depart (d_name) VALUES ("研发部"),("人事部");

从表插入数据

#添加一个符合外键约束的数据
INSERT INTO emp (e_name,d_id) VALUES("大忽悠",1);

在这里插入图片描述


如果添加不符合外键约束的数据,会报错

在这里插入图片描述
这里员工的d_id列的值被depart父表的主键列所约束,即从表的d_id的值必须属于父表的主键列集合里面的id值


小总结

  • 被约束的表成为副表,约束别人的表成为主表,外键设置在副表上
  • 主表(参考表)的参考字段通常为主键
  • 添加数据时,必须先添加主表,后添加副表
  • 修改数据时,必须先修改副表,再修改主表

最后一个修改解释:

例如: 部门表id为3的部门下面有员工,向把部门id的值从3改到4

1.先修改副表,先把员工表外键id=3的员工先挂到其他部门下面,解除部门表id=3和员工表外键id=3的关系

2.再修改主表,解除挂钩之后,就可以修改部门表id的值从3到4,改完之后,再把之前临时挂到其他部门的员工给再挂回到改好的部门


注意事项

#添加一个符合外键约束的数据
INSERT INTO emp (e_name,d_id) VALUES("大忽悠",1);


#添加一个不符合外键约束的数据--该插入语句执行四次
INSERT INTO emp(e_name,d_id) VALUES("小朋友",10);

#添加一个符合外键约束的数据
INSERT INTO emp (e_name,d_id) VALUES("大朋友",2);

在这里插入图片描述
注意观察主键id自增

  • 如果插入的数据因为不符合外键约束插入失败了,主键id依然会自增

在这里插入图片描述
想要删除父表中编号为1的部门,就必须先将该部门下的所有员工删除


级联操作

当有了外键约束的时候,必须先修改或删除副表中的所有关联数据,才能修改或删除主表

但是,我们希望直接修改或删除主表数据,从而影响副表数据,如删除部门表的某个部门,直接自动删除员工表中被删除部门对于的所有员工

这就是级联操作


格式

在定义外键的时候追加以下内容:

级联修改:
ON UPDATE CASCADE
级联删除:
ON DELETE CASCADE

这里选择修改表的时候,添加外键约束

alter table  表名 add [constraint 约束名] 约束类型(字段名)  [外键的引用];

设置级联修改和删除关系

#先将表之前的外键约束删除
ALTER TABLE emp DROP FOREIGN KEY emp_depart_fk;
#修改表时,增加外键约束和级联约束
ALTER TABLE  emp ADD CONSTRAINT emp_depart_fk FOREIGN KEY(d_id) REFERENCES depart(id) 
ON UPDATE CASCADE ON DELETE CASCADE;

测试级联操作

父表
在这里插入图片描述
从表
在这里插入图片描述
修改研发部的部门id,对应员工所属的部门id是否变化

UPDATE depart SET id=3 WHERE d_name="研发部";

在这里插入图片描述
在这里插入图片描述

删除研发部,看研发部下面的员工,是否被自动删除

#删除部门表中部门编号为1的部门
DELETE FROM depart WHERE id=3;

在这里插入图片描述
在这里插入图片描述