数据库的第一、二、三范式分别解决了什么问题?一文详解

张开发
2026/5/21 21:37:01 15 分钟阅读
数据库的第一、二、三范式分别解决了什么问题?一文详解
目录第一范式列的原子性1.核心口号2.解决的问题3.反面教材违反1NF第二范式消除部分依赖1.核心口号2.解决的问题3.反面教材违反2NF第三范式消除传递依赖1.核心口号2.解决的问题3.反面教材违反3NF总结与对比面试必背口诀在数据库设计的面试中“范式”是一个绕不开的高频考点。很多开发者在实际工作中可能习惯“一把梭”把所有字段塞进一张大表里但到了面试现场或者处理复杂业务时就会因为不懂范式而导致数据库设计冗余严重、维护困难。简单来说数据库范式就是一套“拆表规则”。它的核心目的只有一个减少数据冗余避免数据异常插入、更新、删除异常。今天我们就通过具体的案例和表格把第一、二、三范式彻底讲透。第一范式列的原子性1.核心口号“列不能再分。”2.解决的问题第一范式1NF是数据库设计的最基本要求。它要求表中的每一个字段都必须是不可分割的原子值。如果一个字段里存了“多个值”就不符合1NF。3.反面教材违反1NF假设我们有一张学生联系表学号姓名联系方式001张三13800001234, 010-88888888002李四13900005678问题分析“联系方式”这一列里张三既有手机号又有座机号它们被逗号分隔存在同一个格子里。查询困难如果你想查“所有有座机号的学生”SQL写起来会非常麻烦。数据混乱你无法单独约束“手机号”必须是11位数字。修正方案符合1NF将“联系方式”拆分或者将多值转为多行。学号姓名手机号座机号001张三13800001234010-88888888002李四13900005678(空)总结只要你的表里出现了“一组数据”塞在一个格子里的情况就违反了第一范式。第二范式消除部分依赖1.核心口号“不能只靠一半。”2.解决的问题第二范式2NF建立在1NF的基础上。它主要针对复合主键由两个或多个字段共同作为主键的表。它要求表中的非主键字段必须完全依赖于整个主键而不能只依赖主键的一部分。3.反面教材违反2NF假设我们有一张“学生选课成绩表”。一个学生可以选多门课。一门课也可以被多个学生选。所以我们需要用【学号 课程名】这两个字段联合起来才能唯一确定一条记录比如张三的数学成绩。学号 (主键1)课程名 (主键2)成绩学生姓名所在系001数学90张三计算机系001英语85张三计算机系002数学95李四外语系问题分析我们来看看表里的非主键字段成绩、学生姓名、所在系对主键的依赖关系成绩必须知道“谁”学号考了“哪门课”课程名才能确定成绩。这是完全依赖没问题。学生姓名只要知道“学号”是001就知道是“张三”。根本不需要知道“课程名”。这就是部分依赖只依赖了主键的一半。所在系同理只要知道学号就知道他在哪个系跟选了什么课无关。这也是部分依赖。如果不拆表后果很严重数据冗余张三选了10门课“张三”和“计算机系”这两个信息就要重复存储10次。更新异常如果张三转系了或者改名了你需要把这张表里所有属于张三的记录全部找出来修改。漏改一条数据就不一致了。插入异常如果有一个新生比如王五刚入学还没有选课没有课程名你就没法把他的名字存进这张表因为主键的一部分课程名不能为空。修正方案符合2NF把只依赖“学号”的字段拆出去建立新表。表1选课表主键学号课程名学号课程名成绩001数学90001英语85表2学生表主键学号学号学生姓名所在系001张三计算机系002李四外语系总结只要表里有复合主键就要检查有没有字段是“偷懒”的只依赖了主键的一部分。如果有就把它拆出去。第三范式消除传递依赖1.核心口号“不能隔山打牛。”2.解决的问题第三范式3NF建立在2NF的基础上。它要求表中的非主键字段必须直接依赖于主键而不能依赖于另一个非主键字段。即A决定BB决定C那么A决定C就是传递依赖C应该被拆分出去。3.反面教材违反3NF现在我们看上面的“表2学生表”。假设它的主键是学号。学号 (主键)学生姓名所在系系主任001张三计算机系王教授002李四计算机系王教授003王五外语系赵教授问题分析我们来分析依赖关系学号 → 所在系学号决定了学生属于哪个系。所在系 → 系主任一个系通常只有一个系主任所以“所在系”决定了“系主任”。结论“系主任”是通过“所在系”间接依赖于“学号”的。这就是传递依赖。如果不拆表后果很严重数据冗余计算机系有1000个学生“王教授”这个名字就要重复存1000次。更新异常如果王教授退休了换成了李教授。你需要修改学生表里所有“计算机系”对应的1000条记录。插入异常如果学校刚成立了一个“人工智能系”还没有招学生没有学号你就没法把这个新系和它的系主任存进数据库因为主键学号不能为空。修正方案符合3NF把“系主任”这个字段拆出去让“所在系”做主键。表1学生表主键学号学号学生姓名所在系 (外键)001张三计算机系002李四计算机系表2系部表主键所在系所在系系主任计算机系王教授外语系赵教授总结只要发现表里有字段A依赖字段B而字段B又依赖主键那就赶紧把A拆出去。不要让非主键字段之间存在依赖关系。总结与对比为了方便记忆我们可以把这三个范式看作是一个层层递进的“拆表”过程范式核心解决的问题依赖类型案例场景1NF字段不可分无一个格子里存了“手机,座机”。2NF消除部分依赖非主键列只依赖主键的一部分选课表学号课程姓名只依赖学号。3NF消除传递依赖非主键列依赖另一个非主键列学生表学号系主任依赖所在系。面试必背口诀1NF原子性列不可分。2NF完全依赖不依赖主键的一半针对复合主键。3NF直接依赖不隔山打牛消除传递依赖。在实际开发中一般数据库设计达到第三范式就足够了。当然为了性能优化比如减少表连接JOIN有时候我们会适当进行“反范式化”设计但这属于进阶话题前提是你得先懂范式。以上就是本篇文章的全部内容喜欢的话可以留个免费的关注呦~~~

更多文章