考点频率:★★★★★(数据库必考,选择题常考1NF/2NF的判断,下午题常考模式分解)
难度:⭐⭐⭐⭐
建议:重点掌握1NF的定义与判断、2NF的判断方法(是否存在部分函数依赖),以及从1NF到2NF的分解规则
1️⃣ 范式是什么?
范式(Normal Form,NF)是关系数据库规范化过程中,用于衡量关系模式“好与坏”的标准。范式的级别越高,数据冗余越小,异常越少。
打个比方:范式就像“房屋质量等级”。1NF是“能住人”(最基础),2NF是“结构稳定”,3NF是“精装修”。每一级都在上一级的基础上改进。
规范化就是将低一级范式的关系模式,通过模式分解转化为高一级范式的过程。
本节学习目标:
- 1NF:消除“属性不可再分”的问题(最基础的合格线)
- 2NF:消除“部分函数依赖”的问题(让表更聚焦)
2️⃣ 第一范式(1NF,First Normal Form)
2.1 定义
第一范式(1NF)要求:关系中的每个属性都是原子的、不可再分的。
这是关系模型的基本要求——任何关系型数据库中的表,默认都满足1NF(只要你没有把多个值塞到一个字段里)。
2.2 什么样的设计违反1NF?
| 错误设计(违反1NF) | 问题 | 正确设计(满足1NF) |
|---|---|---|
| 学生表(学号, 姓名, 电话列表) 其中 电话列表 = '138..., 139...' | 一个属性包含多个值,不可再分 | 拆分为多行,或另建电话表 |
| 员工表(员工号, 姓名, 地址) 其中 地址 = '安徽省合肥市包河区' | 地址包含省、市、区,可进一步细分 | 拆分为:省、市、区三个属性(如果业务需要按地区查询) |
示例:
❌ 违反1NF: 学生表 | 学号 | 姓名 | 电话号码 | |------|------|---------------| | 001 | 张三 | 1381111,1392222 | ← 一个字段存了多个值 ✅ 满足1NF(方案一:拆行): | 学号 | 姓名 | 电话号码 | |------|------|----------| | 001 | 张三 | 1381111 | | 001 | 张三 | 1392222 | ✅ 满足1NF(方案二:拆列): | 学号 | 姓名 | 电话1 | 电话2 | |------|------|---------|---------| | 001 | 张三 | 1381111 | 1392222 |软考重点:1NF的判断标准很简单——看每个格子是否都只存了“一个值”。如果某个字段存了多个值(如逗号分隔的列表),就违反1NF。大多数关系数据库表天然满足1NF,因为SQL标准不支持在单列中存储多值集合。
2.3 满足1NF后还存在什么问题?
即使满足1NF,如果一张表的主键是组合键,仍可能存在数据冗余和异常。先回顾一个之前用过的例子:
选课表(学号, 课程号, 成绩, 姓名, 班级号)
主键为(学号, 课程号)
| 学号 | 课程号 | 成绩 | 姓名 | 班级号 |
|---|---|---|---|---|
| 001 | C01 | 85 | 张三 | 101 |
| 001 | C02 | 90 | 张三 | 101 |
| 002 | C01 | 78 | 李丽 | 102 |
这张表满足1NF吗?✅ 满足(每个格子只有一个值)。
但它仍有数据冗余——姓名和班级号在001的三条选课记录中重复了三次。
为什么会这样?
因为姓名和班级号只依赖于主键的一部分(学号),而不是整个主键(学号, 课程号)。这就是部分函数依赖,也是2NF要解决的问题。
3️⃣ 第二范式(2NF,Second Normal Form)
3.1 定义
第二范式(2NF)在1NF的基础上,要求:
每一个非主属性都完全函数依赖于候选键,不允许存在非主属性对候选键的部分函数依赖。
通俗理解:一张表的主键如果是组合键,那么所有非主属性必须依赖于整个组合键,不能只依赖于组合键中的一部分。如果主键是单一属性,该表自动满足2NF(因为不存在“部分依赖”的可能性)。
3.2 判断步骤
判断一个关系模式是否满足2NF,按以下步骤进行:
| 步骤 | 操作 |
|---|---|
| 第1步 | 确认该关系满足1NF |
| 第2步 | 找出所有的候选键(可能是组合键) |
| 第3步 | 找出所有的非主属性 |
| 第4步 | 检查每个非主属性是否完全依赖于候选键 |
| 第5步 | 如果存在非主属性只依赖于候选键的一部分→ 违反2NF;否则满足2NF |
3.3 典型反例(选课表)
关系模式:选课表(学号, 课程号, 成绩, 姓名, 班级号)
候选键:(学号, 课程号)
非主属性:成绩、姓名、班级号
函数依赖:
(学号, 课程号) → 成绩✅ 完全依赖学号 → 姓名❌ 姓名只依赖学号,是部分函数依赖学号 → 班级号❌ 班级号只依赖学号,是部分函数依赖
结论:存在非主属性(姓名、班级号)对候选键的部分函数依赖 →不满足2NF。
3.4 如何从1NF提升到2NF?(模式分解)
将违反2NF的表拆分成多张表,消除部分函数依赖:
原表(不满足2NF):
选课表(学号, 课程号, 成绩, 姓名, 班级号)
分解为两张表:
- 选课表(学号, 课程号, 成绩)—— 描述“谁选了哪门课、得了多少分”
- 学生表(学号, 姓名, 班级号)—— 描述“学生的基本信息”
分解后的依赖关系:
- 选课表:候选键
(学号, 课程号),非主属性成绩完全依赖(学号, 课程号)✅ - 学生表:候选键
学号,非主属性姓名、班级号完全依赖学号✅
两张表都满足2NF。
4️⃣ 1NF vs 2NF 对比总结
| 对比项 | 第一范式(1NF) | 第二范式(2NF) |
|---|---|---|
| 基本要求 | 属性不可再分(原子性) | 1NF + 消除部分函数依赖 |
| 关键检查 | 每个格子是否只有一个值 | 非主属性是否完全依赖整个主键(组合键时) |
| 主键为单一属性时 | 需满足 | 自动满足2NF |
| 主键为组合键时 | 需满足 | 需要检查每个非主属性是否依赖整个组合键 |
| 违反后果 | 无法用关系模型表示 | 数据冗余、插入/删除/修改异常 |
| 解决方法 | 拆分属性或拆分行 | 模式分解(将表拆成多张表) |
5️⃣ 经典例题
例题1:关系模式R(A,B,C,D)R(A, B, C, D)R(A,B,C,D),函数依赖集F={(A,B)→C,A→D}F = \{ (A, B) \rightarrow C, A \rightarrow D \}F={(A,B)→C,A→D}。则RRR满足( )。
A. 1NF但不满足2NF
B. 2NF但不满足3NF
C. 3NF
D. BCNF
解析:
- 候选键为(A,B)(A, B)(A,B)
- 非主属性:CCC和DDD
- (A,B)→C(A, B) \rightarrow C(A,B)→C:完全依赖 ✅
- A→DA \rightarrow DA→D:DDD只依赖候选键的一部分(AAA),存在部分函数依赖❌
- 因此RRR满足1NF,但不满足2NF。
选A。
例题2:关系模式R(A,B,C)R(A, B, C)R(A,B,C),函数依赖集F={A→B,B→C}F = \{ A \rightarrow B, B \rightarrow C \}F={A→B,B→C}。则RRR的主键是( ),它是否满足2NF?
A.AAA;满足2NF
B.(A,B)(A, B)(A,B);不满足2NF
C.AAA;不满足2NF
D.(A,B)(A, B)(A,B);满足2NF
解析:
- 候选键是AAA(AAA能决定所有属性:A→BA \rightarrow BA→B,A→CA \rightarrow CA→C通过传递)
- 主键是单一属性,不存在“部分函数依赖”的问题(部分依赖只会出现在组合键中)
- 因此RRR满足2NF(但不满足3NF,因为有传递依赖A→B→CA \rightarrow B \rightarrow CA→B→C)
选A。
6️⃣ 记忆口诀
1NF看原子性,一个格子一个值。
2NF看完全性,非主属性全依赖主键。
组合主键要小心,部分依赖要消除。
单一主键自动过,2NF门槛轻松跨。
7️⃣ 小测验(评论区对答案)
关系模式R(A,B,C,D)R(A, B, C, D)R(A,B,C,D),函数依赖集F={A→B,C→D,(A,C)→D}F = \{ A \rightarrow B, C \rightarrow D, (A, C) \rightarrow D \}F={A→B,C→D,(A,C)→D}。候选键为(A,C)(A, C)(A,C),以下说法正确的是( )。
A. 满足1NF但不满足2NF
B. 满足2NF但不满足3NF
C. 满足3NF
D. 不满足1NF
(提示:先判断有没有违反1NF,再看非主属性是否存在部分函数依赖)
🔔本专栏日更,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容
#软考中级 #软件设计师 #第一范式 #第二范式 #数据库规范化 #数据库技术基础 #软考备考