💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
#### 13.4.4、外键约束,foreign key 外键主要是维护表之间的关系的,主要是为了保证参照完整性,如果表中的某个字段为外键字段,那么该字段的值必须来源于参照的表的主键,如:emp中的deptno值必须来源于dept表中的deptno字段值。 >[danger]注意:外键关联有四种模型 第一种 一对一模型 ,A表的一条记录对应B表中的一条记录 有且只对应一条(t_student t_student_info) 怎么实现:在其中任意一张表定义主键,另外一张表定义外键 与之关联 并且定义外键的这张表要满足唯一约束,但是我们建议在t_student 中 添加主键 >[info]第二种 一对多 ,A表中的一条记录对应B表中的多条记录 (classes t_student) 怎么实现:通常我们在A表中定义一个主键,在B表中添加外键关联A表的主键字段(表中的外键不添加为约束) >[danger] 第三种多对多,A表中一条记录对应B表中的多条记录同时,B表中的一条记录也对应A表中的多条记录(t_student t_subject) 怎么实现:我们要创建第三张关系表,表中只有两个字段,其中一个字段作为外键指向A表,另一个外键指向B表 >[info] 第四种自关联一对多,一般所有的树形结构都可以用此方式来描述 怎么实现:在此表中添加一个字段做为外键关联此表自己的主键 建立学生和班级表之间的连接 首先建立班级表t_classes ``` drop table if exists t_classes; create table t_classes( classes_id int(3), classes_name varchar(40), constraint pk_classes_id primary key(classes_id) ) ``` 在t_student中加入外键约束 ``` drop table if exists t_student; create table t_student( student_id int(10), student_name varchar(20), sex char(2), birthday date, email varchar(30), classes_id int(3), constraint student_id_pk primary key(student_id), constraint fk_classes_id foreign key(classes_id) references t_classes(classes_id) ) ``` 向t\_student中加入数据 ``` insert into t_student(student_id, student_name, sex, birthday, email, classes_id) values(1001, 'zhangsan', 'm', '1988-01-01', 'qqq@163.com', 10) ``` ![](https://img.kancloud.cn/be/ff/beff8f5acd1310d0a07af6e8f795f4ef_643x82.png) 出现错误,因为在班级表中不存在班级编号为10班级,外键约束起到了作用 存在外键的表就是子表,参照的表就是父表,所以存在一个父子关系,也就是主从关系,主表就是班级表,从表就是学生表![](https://img.kancloud.cn/70/ae/70aeaedd304c564a20db4f41d8fca950_651x44.png) 以上成功的插入了学生信息,当时classes\_id没有值,这样会影响参照完整性,所以我们建议将外键字段设置为非空 ``` drop table if exists t_student; create table t_student( student_id int(10), student_name varchar(20), sex char(2), birthday date, email varchar(30), classes_id int (3) not null, constraint student_id_pk primary key(student\_id), constraint fk_classes_id foreign key(classes_id) references t_classes(classes_id) ) insert into t_student(student_id, student_name, sex, birthday, email, cla sses_id) values(1001, 'zhangsan', 'm', '1988-01-01', 'qqq@163.com', null); ``` 再次插入班级编号为null的数据![](https://img.kancloud.cn/42/2d/422dd432b0abc74e8216c9e2426521cd_645x53.png) 添加数据到班级表,添加数据到学生表,删除班级数据,将会出现如下错误: ``` insert into t_classes (classes_id,classes_name) values (10,'366'); insert into t_student( student_id, student_name, sex, birthday, email, classes_id ) values( 1001, 'zhangsan', 'm', '1988-01-01', 'qqq@163.com', 10 ) mysql> update t_classes set classes_id = 20 where classes_name = '366'; 因为子表(t_student)存在一个外键classes_id,它参照了父表(t_classes)中的主键,所以先删除子表中的引用记录,再修改父表中的数据。 我们也可以采取以下措施 级联更新。 mysql> delete from t_classes where classes_id = 10; 因为子表(t_student)存在一个外键classes_id,它参照了父表(t_classes)中的主键,所以先删除父表,那么将会影响子表的参照完整性,所以正确的做法是,先删除子表中的数据,再删除父表中的数据,采用drop table也不行,必须先drop子表,再drop父表 我们也可以采取以下措施 级联删除。 ```