navicat --mysql数据库外键约束及其外键策略

一,什么是外键约束

外键约束(FOREIGN KEY,缩写FK)是用来实现数据库表的参照完整性的。外键约束可以使两张表紧密的结合起来,特别是针对修改或者删除的级联操作时,会保证数据的完整性。

外键是指表中某个字段的值依赖于另一张表中某个字段的值,而被依赖的字段必须具有主键约束或者唯一约束。被依赖的表我们通常称之为父表或者主表,设置外键约束的表称为子表或者从表。

举个例子:如果想要表示学生和班级的关系,首先要有学生表和班级表两张表,然后学生表中有个字段为stu_clazz(该字段表示学生所在的班级),而该字段的取值范围由班级表中的主键cla_no字段(该字段表示班级编号)的取值决定。那么班级表为主表,学生表为从表,且stu_clazz字段是学生表的外键。通过stu_clazz字段就建立了学生表和班级表的关系。

navicat --mysql数据库外键约束及其外键策略_第1张图片

主表(父表):班级表  -  班级编号 - 主键

从表(子表):学生表 - 班级编号 - 外键

 sql语句

  1. -- 先创建父表:班级表:
  2. create table t_class(
  3.         cno int(4) primary key auto_increment,
  4.         cname varchar(10) not null,
  5.         room char(4)
  6. )
  7. -- 添加班级数据:
  8. insert into t_class values (null,'java001','r803');
  9. insert into t_class values (null,'java002','r416');
  10. insert into t_class values (null,'大数据001','r103');
  11. -- 可以一次性添加多条记录:
  12. insert into t_class values (null,'java001','r803'),(null,'java002','r416'),(null,'大数据001','r103');
  13. -- 查询班级表:
  14. select * from t_class;
  15. -- 学生表删除:
  16. drop table t_student;
  17. -- 创建子表,学生表:
  18. create table t_student(
  19.         sno int(6) primary key auto_increment,
  20.         sname varchar(5) not null,
  21.         classno int(4)  -- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同。
  22. );
  23. -- 添加学生信息:
  24. insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2);
  25. -- 查看学生表:
  26. select * from t_student;
  27. -- 出现问题:
  28. -- 1.添加一个学生对应的班级编码为4:
  29. insert into t_student values (null,'丽丽',4);
  30. -- 2.删除班级2:
  31. delete from t_class where cno = 2;
  32. -- 出现问题的原因:
  33. -- 因为你现在的外键约束,没用语法添加进去,现在只是逻辑上认为班级编号是外键,没有从语法上定义
  34. -- 解决办法,添加外键约束:
  35. -- 注意:外键约束只有表级约束,没有列级约束:
  36. create table t_student(
  37.         sno int(6) primary key auto_increment,
  38.         sname varchar(5) not null,
  39.         classno int(4),-- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同。
  40.                                 constraint fk_stu_classno foreign key (classno) references t_class (cno)
  41. );
  42. create table t_student(
  43.         sno int(6) primary key auto_increment,
  44.         sname varchar(5) not null,
  45.         classno int(4)
  46. );
  47. -- 在创建表以后添加外键约束:
  48. alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno)
  49. -- 上面的两个问题都解决了:
  50. -- 添加学生信息:
  51. -- > 1452 - Cannot add or update a child row: a foreign key constraint fails (`mytestdb`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
  52. insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2);
  53. -- 删除班级1:
  54. -- 2.删除班级2:
  55. insert into t_student values (null,'张三',3),(null,'李四',3),(null,'王五',3);
  56. -- > 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`mytestdb`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`))
  57. delete from t_class where cno = 3;

二 ,外键策略

1.no action  不允许操作

2.cascade 级联操作:操作主表的时候影响从表的外键信息:

3,set null  置空操作

sql语句


-- 两个表

-- 学生表和班级表
-- 创建班级表
create table t_class(
    cno int(4) primary key auto_increment,
    cname varchar(16) not null,
    cclass varchar(15)
)

-- 删除班级表
drop table t_class;
-- 查询班级表
select * from t_class;

-- 添加数据
insert into t_class values(null,'大数据','2002B'),(null,'大数据','2003B'),(null,'计算机科学与技术','2002B'); 
insert into t_class values(null,'软件工程','2007B');


-- -- -- -- -- -- -- -- -- -- 

  
-- 创建学生表
-- 添加外键约束  
create table t_student(
    sno int(4) primary key auto_increment,
    sname varchar(15) not null,
    classno int(4),
    constraint fk_atu_classno foreign key (classno) references t_class (cno)
    
)


-- 在表外添加的sql语句 
alter table t_student add constraint fk_atu_classno foreign key t_class (cno);
-- 删除学生表
drop table t_student;
-- 查询学生表
select * from t_student;

-- 添加数据
insert into t_student values(null,'硕硕一号',1),(null,'硕硕二号',2),(null,'硕硕三号',2),(null,'硕硕四号',3),(null,'硕硕五号',4),(null,'硕硕六号',4);
 
-- 外键策略
-- 一:no action 不允许操作
-- 和前面不添加任何东西一样 
 
-- 二:cascade 级联操作:操作主表的时候影响从表的外键信息:
-- 先删除之前的外键约束:
alter table t_student drop foreign key fk_atu_classno;

-- 重新添加外键约束:
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete cascade;

-- 试试更新:
update t_class set cno = 5 where cno = 3;
-- 试试删除:
delete from t_class where cno = 5;

-- 策略3:set null  置空操作:
-- 先删除之前的外键约束:
alter table t_student drop foreign key fk_stu_classno;
-- 重新添加外键约束:
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update set null on delete set null;

-- 试试更新:
update t_class set cno = 8 where cno = 1;  ##运行后会发现没有更新t_student里面得classno变为null
-- 注意:
-- 1. 策略2 级联操作  和  策略2 的  删除操作  可以混着使用:

alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete set null ;

你可能感兴趣的:(数据库,sql,mysql)