目录
Normalization(范式化)
为什么需要 Normalization?
🧩 表格分析:
第一范式(1NF)
什么是第一范式(First Normal Form)?
第二范式(2NF)
什么是第二范式(2NF)?
怎么规范化成 2NF?
第三范式(3NF)
什么是第三范式(3NF)?
当前表违反 3NF 的原因:
规范化为3NF
Normalization(范式化)
为什么需要 Normalization?
目的:
-
减少数据冗余(重复)
-
避免数据不一致
-
提高数据完整性
-
简化维护(插入、更新、删除)
🧩 表格分析:
原始表(未规范化):
Student | Year | Class | Teacher |
---|---|---|---|
John Smith | 9 | Geography | Mr. Green |
Tom Buchanan | 9 | Geography | Mr. Green |
Sarah Bennet | 8 | Physics | Mrs. Einstein |
Charlie Brown | 9 | Geography | Mr. Green |
April Barnes | 10 | Music | Mrs. Sharpe |
这个表的问题:
-
“Geography - Mr. Green” 重复了 3 次。
-
如果某天 Mr. Green 改名了,需要修改所有相关记录 → 数据一致性风险
-
如果 Geography 班级没有学生,无法记录老师信息 → 数据不完整
第一范式(1NF)
什么是第一范式(First Normal Form)?
-
字段中不能有多个值(必须是原子值)
-
字段名不应重复(如 Class1, Class2)
-
每一行记录应代表一个唯一实体的单一信息单位
Student | Year | Class |
---|---|---|
Paul Dawson | 11 | Math |
Peggy Mitchell | 10 | History |
Paul Dawson | 11 | Math |
Brian Cox | 8 | English, Chemistry |
Linda Marsh | 7 | Math, History, Biology |
❌ 为什么这个表不满足第一范式(1NF)?
-
字段“Class”不是原子值(存在多个值组合成一个字段):
-
Brian Cox 的 Class 是 “English, Chemistry”(包含多个课程)
-
Linda Marsh 的 Class 是 “Math, History, Biology”
-
这违反了 1NF 的“每个字段必须只包含一个值”的规则。
-
-
存在重复行(Paul Dawson 出现了两次,内容完全一样)。
规范化后的学生信息表
💡 拆解多值字段 → 变为多行,每行只包含一个原子值
学生姓名(Student) | 年级(Year) | 课程(Class) |
---|---|---|
Paul Dawson | 11 | Math |
Peggy Mitchell | 10 | History |
Paul Dawson | 11 | Math |
Brian Cox | 8 | English |
Brian Cox | 8 | Chemistry |
Linda Marsh | 7 | Math |
Linda Marsh | 7 | History |
Linda Marsh | 7 | Biology |
第二范式(2NF)
什么是第二范式(2NF)?
2NF 的定义: 一个表满足 2NF,要求它首先是 1NF,且不能有任何“非主属性”对主键的部分依赖。
通俗讲:
-
如果主键是复合主键(比如由 Student, Subject 组成),
-
那么其他字段(如 Age) 必须依赖于整个主键,而不能只依赖主键的一部分。
❌ 看看这个表的问题在哪:
Student | Subject | Grade | Age |
---|---|---|---|
Natasha Williams | Maths | A | 15 |
Natasha Williams | English | B | 15 |
Daniel James | Maths | C | 16 |
Simon Brown | Chemistry | A | 14 |
Emma Thomas | Geography | B | 14 |
-
Grade
依赖于整个(Student + Subject)
,这是 OK 的 -
但
Age
只依赖于Student
,不依赖 Subject → 部分依赖!
怎么规范化成 2NF?
我们要“消除部分依赖” → 拆成两个表:让每张表中,非主属性都完全依赖主键。
表一:成绩表(以 Student + Subject
为主键)
Student | Subject | Grade |
---|---|---|
Natasha Williams | Maths | A |
Natasha Williams | English | B |
Daniel James | Maths | C |
Simon Brown | Chemistry | A |
Emma Thomas | Geography | B |
表二:学生基本信息表(以 Student
为主键)
Student | Age |
---|
Natasha Williams | 15 |
Daniel James | 16 |
Simon Brown | 14 |
Emma Thomas | 14 |
-
主键:
Student
-
非主属性:
Age
-
Age
完全依赖于Student
,符合第二范式 ✅
第三范式(3NF)
什么是第三范式(3NF)?
一个关系模式满足 3NF,需要:
-
满足 2NF;
-
所有非主属性 必须直接依赖主键,不能依赖其他非主属性(即消除传递依赖)。
原始表:
Subject | Year | Star Pupil | Star Pupil Date Of Birth |
---|---|---|---|
Math | 2015 | Matthew Taylor | 1999-03-21 |
Physics | 2015 | William Edwards | 1999-09-15 |
Chemistry | 2015 | Georgina Simon | 1998-11-04 |
Math | 2016 | Benjamin Long | 2000-05-02 |
Physics | 2016 | William Edwards | 1999-09-15 |
当前表违反 3NF 的原因:
-
主键候选是
(Subject, Year)
-
Star Pupil
是依赖于(Subject, Year)
✅ -
但是
Star Pupil Date Of Birth
是依赖于Star Pupil
❌ → 传递依赖存在
规范化为3NF
表一:课程之星表
主键:Subject + Year,非主键:Star Pupil)
Subject | Year | Star Pupil |
---|---|---|
Math | 2015 | Matthew Taylor |
Physics | 2015 | William Edwards |
Chemistry | 2015 | Georgina Simon |
Math | 2016 | Benjamin Long |
Physics | 2016 | William Edwards |
表二:学生信息表
(主键:Star Pupil,非主键:Date of Birth)
Star Pupil | Date of Birth |
---|---|
Matthew Taylor | 1999-03-21 |
William Edwards | 1999-09-15 |
Georgina Simon | 1998-11-04 |
Benjamin Long | 2000-05-02 |
通过拆分:
-
我们将“课程→之星学生”和“学生→出生日期”的两种关系分离;
-
保证每个非主属性直接依赖其所属表的主键;