前提知识
设K为关系模式R(U, F)中的属性或属性集合。若K→U,则K称为R的一个超码(Super Key)。
– 候补码:如果在一张表中,一个属性或属性组,被所有属性(U/U就是所有属性)所完全依赖,则称这个属性(属性组)为该表的候补码。
– 候选码是超码中最小的一个。
– 超码包含完全依赖和部分依赖。
– 例如:该表中的候补码为:(球员编号,比赛编号)————>(姓名,年龄,比赛时间,比赛场地,得分)它可以唯一确定整个属性集合。
主属性:组成候选码的属性称为主属性(Prime Attribute)(注意:单个属性而不是属性组)
非主属性:不参加任何候选码的属性称为非主属性(Non-KEY Attribute)。
– 主码若关系模式R有多个候选码,则选定其中的一个做为主码(主键)(Primary key)。(一般情况下关系中就只有一个候选码自然就是主码)
函数依赖
– 1.函数依赖:A–>B,如果通过A属性(属性组)的值,可以唯一确定B属性的值。则称B依赖于A
– 例如:学号–>姓名。 (学号,课程名称)–>分数
– 2.完全函数依赖: 如果A是一个属性组,则B属性值的确定需要依赖于A属性组中所有的属性值。
– 例如:(学号,课程名称) --> 分数 (只有学号和课程名称都知道才能唯一确定某位同学的某课确切成绩)
– 少一个属性都不能唯一确定分数
– 3.部分函数依赖: 如果A是一个属性组,则B属性值的确定只需要依赖于A属性组中某一些值即可。
– 例如:(学号,课程名称) – > 姓名 (只需要知道学号即可)
– 可以少某些属性
– 4.传递函数依赖:如果通过A属性(属性组)的值,可以确定唯一B属性的值,
– 再通过B属性(属性组)的值可以确定唯一C属性的值,则称C传递函数依赖于A
– 例如:学号–>系名(专业),系名(专业)–>系主任
范式
第 1 范式:每一列都是不可再分割的原子数据项(隐藏含义:1.有一个字段(属性组)的值无重复数据,得有主键,也就是有个字段得具有唯一性
2.字段不可再分)
例如:地址字段就包含了省、市等内容,需要再分割。
第 2 范式:在1NF的基础上,非码属性(非主属性)必须完全依赖于候选码(主键)
简化:在1NF的基础上,非主键字段必须完全依赖于主键(消除部分依赖)
例子:
学生编号+教师编号(pk主键)
学生编号 | 教师编号 | 学生姓名 | 教师姓名 |
---|---|---|---|
1001 | 001 | 张三 | 王老师 |
1002 | 002 | 李四 | 赵老师 |
1003 | 001 | 王五 | 王老师 |
1001 | 002 | 张三 | 赵老师 |
上面表出现了部分依赖(一般是多对多关系),“王老师”依赖教师编号001,产生了数据冗余
解决办法:
创建三张表
学生表
学生编号 | 学生姓名 |
---|---|
1001 | 张三 |
1002 | 李四 |
1003 | 王五 |
教师表
教师编号 | 教师姓名 |
---|---|
001 | 王老师 |
002 | 赵老师 |
学生教师关系表
id(pk) | 学生编号(fk) | 教师编号(fk) |
---|---|---|
1 | 1001 | 001 |
2 | 1002 | 002 |
3 | 1003 | 001 |
4 | 1001 | 002 |
多对多,三张表,关系表两个外键
第 3 范式:在2NF基础上,任何非主属性不依赖于其它非主属性
简化:在2NF基础上,所有非主键字段必须直接依赖主键,不要产生传递依赖。
例子
学生编号(pk) | 学生姓名 | 班级编号 | 班级名称 |
---|---|---|---|
1001 | 张三 | 01 | 一年级一班 |
1002 | 李四 | 02 | 一年级二班 |
1003 | 王五 | 03 | 一年级三班 |
1004 | 赵六 | 03 | 一年级三班 |
满足第一范式和第二范式(主键是单一主键),但是一年级一班依赖01,01依赖1001,产生传递依赖。
不符合第三范式。产生数据冗余
解决办法:(因为是一对多关系)用两张表
班级表:一
班级编号(pk) | 班级名称 |
---|---|
01 | 一年级一班 |
02 | 一年级二班 |
03 | 一年级三班 |
学生表:多
学生编号(pk) | 学生姓名 | 班级编号(fk) |
---|---|---|
1001 | 张三 | 01 |
1002 | 李四 | 02 |
1003 | 王五 | 03 |
1004 | 赵六 | 03 |
一对多,两张表,多的表加外键
一对一,外键唯一