范式
范式
| 范式 | 目标 | 关键要求 |
|---|---|---|
| 1NF | 确保原子性 | 每个字段必须包含不可再分的值,表中每列的值是原子值。 |
| 2NF | 消除部分依赖 | 满足1NF,且所有非主键字段完全依赖于主键(消除部分依赖)。 |
| 3NF | 消除传递依赖 | 满足2NF,且非主键字段直接依赖于主键,避免传递依赖。 |
| BCNF | 每个决定因素必须是候选键 | 满足3NF,且每个非平凡的函数依赖的左边部分必须是候选键。 |
| 4NF | 消除多值依赖 | 满足BCNF,且每个多值依赖被消除,避免冗余数据。 |
1.第一范式(1NF)-原子性
每个字段必须包含原子值,表中的每列不能包含集合、数组或重复的值
不符合1NF的例子:
学生ID | 学生姓名 | 电话号码
-------------------------------------------
1 | 张三 | 123456789, 987654321
2 | 李四 | 111222333, 444555666
在表中,电话号码列包含了多个电话号码,违反了1NF的的原子性要求
符合1NF的例子:
学生ID | 学生姓名 | 电话号码
---------------------------
1 | 张三 | 123456789
1 | 张三 | 987654321
2 | 李四 | 111222333
2 | 李四 | 444555666
我们将多个电话号码分到不同的行,每个字段只包含一个值,符合1NF。
2.第二范式(2NF) -消除部分依赖
满足1NF,并消除部分依赖。即所有非主键字段必须以来主键,不能仅依赖于主键的一部分(适用于符合主键)
不符合2NF的例子:
学生ID | 课程ID | 教师 | 成绩
---------------------------
1 | 101 | 王老师 | 85
1 | 102 | 李老师 | 90
2 | 101 | 王老师 | 88
2 | 103 | 张老师 | 92
这里,教师只依赖于课程ID,不依赖于复合主键(学生ID,课程ID)。这是部分依赖,不符合
2NF。
符合2NF的例子:
-- 学生成绩表
学生ID | 课程ID | 成绩
---------------------------
1 | 101 | 85
1 | 102 | 90
2 | 101 | 88
2 | 103 | 92
-- 课程信息表
课程ID | 教师
--------------
101 | 王老师
102 | 李老师
103 | 张老师
把教师信息移到单独的课程信息表,这样教师字段不再依赖于复合主键的部分,而依赖于课程ID
3.第三范式(3NF) -消除传递依赖
满足2NF,并且消除传递依赖。也就是非主键字段不能依赖于其他主键字段。所有非主键字段必须直接依赖于主键,而不是通过其他非主键字段传递依赖
不符合3NF的例子:
学生ID | 学生姓名 | 学生地址 | 地址邮政编码
------------------------------------------
1 | 张三 | 北京市 | 100000
2 | 李四 | 上海市 | 200000
这里,地址邮政编码依赖于学生地址,而学生地址依赖于学生姓名。这是一个传递依赖,因为学生地址和地址邮政编码都是非主键字段,但地址邮政编码间接依赖于学生ID。不满足3NF的需求。
符合3NF的例子:
-- 学生信息表
学生ID | 学生姓名 | 学生地址
-------------------------
1 | 张三 | 北京市
2 | 李四 | 上海市
-- 地址信息表
学生地址 | 地址邮政编码
---------------------
北京市 | 100000
上海市 | 200000
将地址邮政编码字段移动到一个单独的表中,确保地址邮政编码直接依赖于学生地址,而不再通过学生地址间接依赖于学生ID,符合3NF。
4.BCNF(博伊斯-科得范式)
BCNF要求每一个非平凡的函数依赖的决定因素(determinant)必须是候选键。换句话说,BCNF要求每个函数依赖的左边必须是候选键。这样可以进一步消除数据冗余和异常。
1. BCNF与3NF的关系
- 3NF要求:一个表必须消除传递依赖。非主键字段必须直接依赖于主键。
- BCNF要求:更严格地要求每个依赖关系的决定因素(即函数依赖的左边部分)必须是候选键。
函数依赖的定义:
- 决定因素(determinant):一个字段或一组字段,决定了另一个字段的值。
- 非平凡依赖:依赖关系中,决定因素不完全等于右边的字段。
3NF能够处理大多数的数据冗余问题,但对于一些特殊情况,3NF仍然不能完全消除冗余,BCNF则进一步加强了这一点。
2. 不符合BCNF的例子
我们来看一个不符合BCNF的例子:
假设我们有一个表格记录学生、课程和教师的信息:
学号 | 课程ID | 教师 | 成绩
--------------------------
1 | 101 | 王老师 | 85
1 | 102 | 李老师 | 90
2 | 101 | 王老师 | 88
2 | 103 | 张老师 | 92
存在的依赖关系:
学号, 课程ID → 成绩(每个学生在每门课程中的成绩是唯一的)课程ID → 教师(每门课程对应一个固定的教师)
根据这些依赖关系,表中的课程ID → 教师是一个依赖关系,但课程ID并不是一个候选键,而是一个普通的非主键字段。这样,表中的教师字段就依赖于课程ID,而课程ID并不是表的候选键。因此,这个表不符合BCNF。
符合BCNF的表结构
为了让表符合BCNF,我们需要调整表结构,确保每个非主键字段只依赖于候选键。我们可以将表拆分成两个表:
学生课程成绩表:
CREATE TABLE StudentCourse ( 学号 INT, 课程ID INT, 成绩 DECIMAL(5, 2), PRIMARY KEY (学号, 课程ID) );课程教师表:
CREATE TABLE CourseTeacher ( 课程ID INT, 教师 VARCHAR(50), PRIMARY KEY (课程ID) );
这样,我们将课程与教师的信息拆分成了一个单独的表,消除了课程ID → 教师的依赖,确保每个表的非主键字段完全依赖于其主键(即每个表中的字段都依赖于候选键)。
BCNF通过严格要求每个非平凡的依赖的决定因素必须是候选键,进一步消除了数据库中的冗余数据和不一致的情况。与3NF相比,BCNF处理了3NF无法解决的部分依赖问题,避免了数据冗余。
简单总结:
- 3NF 解决了传递依赖问题,确保了非主键字段之间不会发生依赖。
- 4NF 解决了多值依赖问题,通过将独立的多值属性分开存储,避免了数据冗余和一致性问题。
- BCNF:进一步要求每个函数依赖的左边部分必须是候选键,解决了3NF中某些特殊情况下的冗余问题。
BCNF比3NF更严格,它能有效避免一些边缘情况的依赖问题,确保数据结构更加规范化。
5.第四范式(4NF) -消除多值依赖
满足BCNF,并且消除多值依赖。多值依赖是指一个字段依赖于多个其他字段,而这些依赖之间没有直接关系,通常涉及多个独立的多值属性
目的:消除多值依赖,减少数据冗余,避免数据不一致。
不符合4NF的例子:
学生ID | 学生姓名 | 学生爱好 | 学生课程
----------------------------------------
1 | 张三 | 游泳, 画画 | 数学, 物理
2 | 李四 | 足球 | 化学, 英语
在上面的表中,学生爱好和学生课程字段同时依赖于学生ID,但是它们是独立的属性,没有直接关系。由于每个学生可以有多个爱好和多个课程,表中的数据变得冗余,而且插入和更新操作可能会导致数据的不一致性,这是典型的多值依赖。
符合4NF的例子:
sql复制编辑-- 学生爱好表
学生ID | 学生爱好
-------------------
1 | 游泳
1 | 画画
2 | 足球
-- 学生课程表
学生ID | 学生课程
-------------------
1 | 数学
1 | 物理
2 | 化学
2 | 英语
我们将学生的爱好和课程拆分成两个独立的表,这样就消除了多值依赖,确保每个表中的每一行都只能存储一个独立的值。这样既避免了冗余数据,又提高了数据的一致性和可维护性,符合4NF。




