数据库中常见的三大范式有:第一范式、第二范式、第三范式。
第一范式
数据表的列具有原子性,不可再分。
比如下表就不满足第一范式,因为选课这一列明显是可以再分的。
学号 | 姓名 | 选课 |
---|---|---|
10001 | 张三 | 数学、语文、英语 |
10002 | 李四 | 语文、英语 |
10003 | 王五 | 数学、英语、历史 |
第二范式
第二范式是指,首先满足第一范式,并且表中非主键列不存在对主键的部分依赖。
看下面的一张学生选课表:
学号 | 课程 | 成绩 | 课程学分 |
---|---|---|---|
10001 | 数学 | 100 | 5 |
10001 | 语文 | 90 | 3 |
10001 | 英语 | 82 | 4 |
10002 | 数学 | 70 | 5 |
10003 | 数学 | 93 | 5 |
10004 | 语文 | 81 | 3 |
上面的表就不满足第二范式,表中主键为 (学号,课程),我们可以表示为 (学号,课程) -> (成绩,课程学分), 表示所有非主键列 (成绩,课程学分)都依赖于主键 (学号,课程)。 但是,表中还存在另外一个依赖:(课程)->(课程学分)。这样非主键列 ‘课程学分’依赖于部分主键列 ‘课程’, 所以上表是不满足第二范式的。将上表做拆分如下:
学生选课表:
学号 | 课程 | 成绩 |
---|---|---|
10001 | 数学 | 100 |
10001 | 语文 | 90 |
10001 | 英语 | 82 |
10002 | 数学 | 70 |
10003 | 数学 | 93 |
10004 | 语文 | 81 |
课程信息表:
课程 | 课程学分 |
---|---|
数学 | 5 |
语文 | 3 |
英语 | 4 |
那么上面2个表,学生选课表主键为(学号,课程),课程信息表主键为(课程),表中所有非主键列都完全依赖主键。不仅符合第二范式,还符合第三范式。
第三范式
第三范式定义是,满足第二范式,并且表中的列不存在对非主键列的传递依赖。
学生信息表:
学号 | 姓名 | 性别 | 班级 | 班主任 |
---|---|---|---|---|
10001 | 张三 | 男 | 高一(1)班 | 小沈 |
10002 | 李四 | 男 | 高一(2)班 | 小钱 |
10003 | 王五 | 男 | 高一(8)班 | 小陈 |
10004 | 葛六 | 男 | 高一(8)班 | 小陈 |
上面的学生信息表,虽然满足第二范式,所有字段都依赖主键(学号),但是,表中存在一个传递依赖,(学号)-> (班级)->(班主任)。也就是说,(班主任)这个非主键列依赖与另外一个非主键列 (班级)。所以不符号第三范式。将上表做拆分如下:
学生信息表:
学号 | 姓名 | 性别 | 班级 |
---|---|---|---|
10001 | 张三 | 男 | 高一(1)班 |
10002 | 李四 | 男 | 高一(2)班 |
10003 | 王五 | 男 | 高一(8)班 |
10004 | 葛六 | 男 | 高一(8)班 |
班级信息表
班级 | 班主任 |
---|---|
高一(1)班 | 小沈 |
高一(2)班 | 小钱 |
高一(8)班 | 小陈 |
这样,对主键的传递依赖就消失了。上面的2个表都符合第3范式。