说明

在表关系中,多对多的情况一般使用一张中间表用来维护他们之间的关系
但是如果不加相关的约束,会出现如下问题

  1. 中间表中可以插入不存在的程序员id或者项目id信息
  2. 主表删除信息后,中间表信息依旧保存,不能统一
  3. 主表主键更新后,对应的中间表数据没有同步

上述问题,可以给中间表添加外键约束来解决

语法

  1. -- 方式1:修改字段为外键
  2. alter table 表名 add constraint 外键名称 foreign key(当前表中的字段) references 主表(主表主键);
  3. /*
  4. 说明:
  5. constraint 外键名称 :表示约束,同时给约束取名称
  6. foreign key(当前表中的字段):表示给当前表字段添加外键
  7. references 主表(主表主键):表示关联主表中的主键
  8. */
  9. -- 方式2:创建表时创建外键
  10. create table coder_project(
  11. coder_id int,
  12. project_id int,
  13. constraint c_id_fk foreign key(coder_id) references coder(id),
  14. constraint p_id_fk foreign key(project_id) references porject(id)
  15. );

案例

为中间表添加外键
说明:如果中间表中有不正确的数据,比如 coder_idproject_id 在程序员表和项目表中都不存在,此时,给中间表添加外键约束时不能成功的,只有删除掉错误的数据接下来才能添加外键约束

alter table coder_project add constraint fk_coder_id foreign key(coder_id) references coder(id);
alter table coder_project add constraint fk_project_id foreign key(project_id) references project(id);

执行,成功之后,就可以看到外键约束了
image-20220417215246602
接下里,测试,有以下情况

  1. 由于中间表存在 coder_id 为1,project_id 为1的数据,所以在程序员表中删除id为1的用户失败,在项目表中删除id为1的项目失败
  1. 在中间表添加数据,coder_idproject_id为10和20,但是这2个数值在程序员表和项目表中,并不存在,所以也添加失败
  1. 由于中间表存在 coder_id 为1,project_id 为1的数据,所以在程序员表中修改id为1的用户失败,在项目表中修改id为1的项目失败

外键的级联

级联操作就是在修改或者删除主键时可以同时对从表的外键进行修改删除
语法

on udpate cascade:代表主表进行更新操作后,从表对应的也要进行更新操作
on delete cascade:代表主表进行主键删除后,从表外键对应的数据也要删除

演示

-- 先删除外键(可通过navicat删除)

-- 在重新添加外键
alter table coder_project add constraint fk_coder foreign key(coder_id) references coder(id) on update cascade on delete cascade;
alter table coder_project add constraint fk_project foreign key(project_id) references project(id) on update cascade on delete cascade;

-- 测试删除id为3的用户(可以看到中间表中coder_id为3的记录也被删除了)
delete from coder where id = 3;