学号 | 课程 | 成绩 | 课程学分 |
---|---|---|---|
10001 | 数学 | 100 | 6 |
10001 | 语文 | 90 | 2 |
10001 | 英语 | 85 | 3 |
10002 | 数学 | 90 | 6 |
10003 | 数学 | 99 | 6 |
10004 | 语文 | 89 | 2 |
表中主键为 (学号,课程),我们可以表示为 (学号,课程) -> (成绩,课程学分), 表示所有非主键列 (成绩,课程学分)都依赖于主键 (学号,课程)。 但是,表中还存在另外一个依赖:(课程)->(课程学分)。这样非主键列 ‘课程学分‘ 依赖于部分主键列 '课程‘, 所以上表是不满足第二范式的。
我们把它拆成如下2张表:
学生选课表:
学号 | 课程 | 成绩 |
---|---|---|
10001 | 数学 | 100 |
10001 | 语文 | 90 |
10001 | 英语 | 85 |
10002 | 数学 | 90 |
10003 | 数学 | 99 |
10004 | 语文 | 89 |
课程信息表:
课程 | 课程学分 |
---|---|
数学 | 6 |
语文 | 3 |
英语 | 2 |
那么上面2个表,学生选课表主键为(学号,课程),课程信息表主键为(课程),表中所有非主键列都完全依赖主键。不仅符合第二范式,还符合第三范式。
再看这样一个学生信息表:
学号 | 姓名 | 性别 | 班级 | 班主任 |
---|---|---|---|---|
10001 | 张三 | 男 | 一班 | 小王 |
10002 | 李四 | 男 | 一班 | 小王 |
10003 | 王五 | 男 | 二班 | 小李 |
10004 | 张小三 | 男 | 二班 | 小李 |
上表中,主键为:(学号),所有字段 (姓名,性别,班级,班主任)都依赖与主键(学号),不存在对主键的部分依赖。所以是满足第二范式。
第三范式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主键字段。就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放(能尽量外键join就用外键join)。很多时候,我们为了满足第三范式往往会把一张表分成多张表。
即满足第二范式前提,如果某一属性依赖于其他非主键属性,而其他非主键属性又依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。 通俗解释就是一张表最多只存两层同类型信息。
反三范式
没有冗余的数据库未必是最好的数据库,有时为了提高运行效率,提高读性能,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,减少了查询时的关联,提高查询效率,因为在数据库的操作中查询的比例要远远大于DML的比例。但是反范式化一定要适度,并且在原本已满足三范式的基础上再做调整的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。