mysql如何通俗地理解三个范式?
封面图
•
2026-01-06
•
MySQL
208
0
0
0
在 MySQL 中,**数据库设计的三个范式**(1NF、2NF、3NF)是用于**优化数据库结构、减少数据冗余、提高数据一致性**的一套规则。我们可以用一个通俗的例子来理解这三个范式。 --- ### 🧩 一、第一范式(1NF):**消除重复组** #### 通俗理解: > **每个字段只能存储一个值,不能有多个值。** #### 举个例子: 假设我们有一个“学生表”,里面记录学生的姓名和所学课程: | 学生ID | 姓名 | 课程 | |--------|--------|------------------| | 1 | 张三 | 数学, 英语 | | 2 | 李四 | 物理, 化学 | 这个表不符合第一范式,因为“课程”字段里有多个值(数学、英语),这会导致查询困难、数据不一致等问题。 #### 改成符合1NF的结构: | 学生ID | 姓名 | 课程 | |--------|--------|--------| | 1 | 张三 | 数学 | | 1 | 张三 | 英语 | | 2 | 李四 | 物理 | | 2 | 李四 | 化学 | ✅ 每个字段只存一个值,没有重复组。 --- ### 🧩 二、第二范式(2NF):**消除部分依赖** #### 通俗理解: > **如果一个表有多个主键,那么非主键字段必须完全依赖于整个主键,而不是其中一部分。** #### 举个例子: 假设我们有一个“选课表”,包含学生ID、课程ID、课程名称、成绩: | 学生ID | 课程ID | 课程名称 | 成绩 | |--------|--------|----------|------| | 1 | 101 | 数学 | 90 | | 1 | 102 | 英语 | 85 | | 2 | 101 | 数学 | 88 | 这里,“课程名称”只依赖于“课程ID”,而和“学生ID”无关。所以它就**部分依赖**于主键(学生ID + 课程ID)中的一部分。 #### 改成符合2NF的结构: - 把“课程信息”单独放到一个表中: **课程表:** | 课程ID | 课程名称 | |--------|----------| | 101 | 数学 | | 102 | 英语 | **选课表:** | 学生ID | 课程ID | 成绩 | |--------|--------|------| | 1 | 101 | 90 | | 1 | 102 | 85 | | 2 | 101 | 88 | ✅ 现在“课程名称”只存在于课程表中,不再出现在选课表中,避免了部分依赖。 --- ### 🧩 三、第三范式(3NF):**消除传递依赖** #### 通俗理解: > **非主键字段不能依赖于其他非主键字段。** #### 举个例子: 假设我们有一个“学生表”: | 学生ID | 姓名 | 班级ID | 班级名称 | |--------|--------|--------|----------| | 1 | 张三 | 1 | 高一(1)班 | | 2 | 李四 | 2 | 高一(2)班 | 这里,“班级名称”依赖于“班级ID”,而“班级ID”又属于主键的一部分(可能学生ID是主键)。这样,“班级名称”就**间接依赖**于主键,属于传递依赖。 #### 改成符合3NF的结构: - 把“班级信息”单独放到一个表中: **班级表:** | 班级ID | 班级名称 | |--------|----------| | 1 | 高一(1)班 | | 2 | 高一(2)班 | **学生表:** | 学生ID | 姓名 | 班级ID | |--------|--------|--------| | 1 | 张三 | 1 | | 2 | 李四 | 2 | ✅ 现在“班级名称”不再出现在学生表中,避免了传递依赖。 --- ### ✅ 总结 | 范式 | 通俗理解 | 目的 | |------|----------|------| | 1NF | 每个字段只存一个值 | 消除重复组 | | 2NF | 非主键字段要完全依赖主键 | 消除部分依赖 | | 3NF | 非主键字段不能依赖其他非主键字段 | 消除传递依赖 | --- ### 💡 小提示 - 实际开发中,**不一定非要严格遵守三范式**,有时候为了性能会进行**反范式化设计**(比如适当冗余数据)。 - 但**了解范式**对数据库设计是非常有帮助的。 如果你愿意,我可以再用一个更生活化的例子帮你理解。
上一篇:
mysql 主键、外键和索引的区别?
下一篇:
mysql索引的作用?和它的优点缺点是什么?
标题录入,一次不能超过6条
留言
评论