目录
外键约束(foreign key,简称FK)非常重要五颗星*****
4. 思考:子表中的外键引用的父表中的某个字段,被引用的这个字段必须是主键吗?
外键约束(foreign key,简称FK)非常重要五颗星*****
1. 外键约束涉及到的相关术语:
- 外键约束:一种约束(foreign key)
- 外键字段:该字段上添加了外键约束
- 外键值:外键字段当中的每一个值。
2. 业务背景
请设计数据库表,来描述“班级和学生”的信息?
2.1 第一种方案:班级和学生存储在一张表中
t_student
分析以上方案的缺点:
- 数据冗余,空间浪费!!!!
- 这个设计是比较失败的!
2.2 第二种方案:班级一张表、学生一张表
t_class 班级表
t_student 学生表
当cno字段没有任何约束的时候,可能会导致数据无效。可能出现一个102,但是102班级不存在。所以为了保证cno字段中的值都是100和101,需要给cno字段添加外键约束。那么:cno字段就是外键字段,cno字段中的每一个值都是外键值。
注意:
- t_class是父表
- t_student是子表
删除表的顺序?
- 先删子,再删父。
删除数据的顺序?
- 先删子,再删父。
创建表的顺序?
- 先创建父,再创建子。
插入数据的顺序?
- 先插入父,再插入子。
3. 演示上述2.2第二种方案来设计数据库表
references:引用
t_student.sql 文件中的sql语句
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
classno int primary key,
classname varchar(255)
);
create table t_student(
no int primary key auto_increment,
name varchar(255),
cno int,
foreign key(cno) references t_class(classno)
);
insert into t_class(classno, classname) values(100, '北京市大兴区亦庄镇第二中学高三1班');
insert into t_class(classno, classname) values(101, '北京市大兴区亦庄镇第二中学高三1班');
insert into t_student(name,cno) values('jack', 100);
insert into t_student(name,cno) values('lucy', 100);
insert into t_student(name,cno) values('lilei', 100);
insert into t_student(name,cno) values('hanmeimei', 100);
insert into t_student(name,cno) values('zhangsan', 101);
insert into t_student(name,cno) values('lisi', 101);
insert into t_student(name,cno) values('wangwu', 101);
insert into t_student(name,cno) values('zhaoliu', 101);
select * from t_student;
select * from t_class;
4. 思考:子表中的外键引用的父表中的某个字段,被引用的这个字段必须是主键吗?
不一定是主键,但至少要有unique约束
5. 测试:外键可以为NULL吗?
外键值可以为NULL
insert into t_student(name) values('wangwuliu');
select * from t_student;