ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

10.数据库设计入门:从学生视角看三大范式与软性约定

2026/8/9 10:19:05 拓冰建站 浏览量
10.数据库设计入门:从学生视角看三大范式与软性约定

目录

一、数据库设计:了解为主,少数记背

二、范式:软性约定,不是硬性规定

三、三大范式:简单了解,实践中体会

1. 第一范式(1NF):列必须是“原子数据”

2. 第二范式(2NF):消灭“部分函数依赖”

3. 第三范式(3NF):消灭“传递依赖”

四、总结


一、数据库设计:了解为主,少数记背

“数据库设计以了解为主,不需要死记硬背,少数关键地方要记住”。后面开发写多了表、写多了代码,自然能找到更优解——别一开始就死磕理论,实践出真知~

二、范式:软性约定,不是硬性规定

范式是设计数据库表的基本规范和约定,就像写代码的“最佳实践”“指导方针”。

  • 它和create table语法不同:create table硬性的语法规定(必须严格遵守);

  • 范式是软性的约定(日常开发遵守到第三范式即可,其他高阶范式一般不用考虑)。

三、三大范式:简单了解,实践中体会

日常开发常见场景,遵守到第三范式就够用了。下面逐个拆解,结合课堂截图理解:

1. 第一范式(1NF):列必须是“原子数据”

第一范式的核心是:数据表的每一列都是不可分割的原子数据项,不能是集合、数组、对象这类“非原子数据”。

MySQL 本身没有数组/对象这样的类型,所以建表时要注意列的“原子性”。举两个反例:

  • 反例1:class表设计成(classId, name, studentId),其中studentId用逗号分隔(比如1,2,3,4)。这违反了第一范式——因为studentId列可以拆分成多个独立的学生ID,不是“原子”的。

  • 反例2:学生表的“学校”列,直接存“学校名+学校地址+学校电话”(比如“XX大学+XX路XX号+123456”)。这也能继续拆分,所以也违反第一范式。

2. 第二范式(2NF):消灭“部分函数依赖”

第二范式的前提是满足第一范式,然后要求:不存在非关键字段对任意候选键的“部分函数依赖”

先明确几个概念:

  • 候选键:可以理解成主键(一条记录的身份标识),可以是单个列,也可以是多列组合(联合主键)。

  • 非关键字段:不属于候选键的列。

  • 部分函数依赖:不必通过完整的候选键,就能确定一个记录(比如只靠学号,就能确定学生姓名)。

  • 完全函数依赖:必须通过完整的候选键,才能确定一个记录(比如成绩需要“学号+课程名”一起确定)。

来看一个“学生课程成绩表”例子:

这个表的候选键是“学号 + 课程名”(因为只有这两个组合能唯一确定一条记录)。但存在很多问题:

  • 学生姓名、年龄、性别:只依赖“学号”(部分依赖,不用看课程名就知道是谁);

  • 学分:只依赖“课程名”(部分依赖,不用看学号就知道是哪门课的学分);

  • 成绩:依赖“学号+课程名”(完全依赖,必须两者结合才知道成绩)。

这种“部分依赖”会导致数据冗余(比如李四的姓名和年龄,每次选不同课程都要存一次,重复了)和维护灾难(比如改李四的年龄,要改所有他选课的行,漏改就会歧义)。

所以第二范式的约束是:消灭部分依赖——通常做法是拆分表(比如把学生信息单独放“学生表”,课程信息放“课程表”,成绩放“分数表”)。

3. 第三范式(3NF):消灭“传递依赖”

第三范式的前提是满足第二范式,然后要求:不存在非关键字段对候选键的“传递依赖”

简单说,就是“非关键字段不能依赖另一个非关键字段”。比如:如果 A→B,B→C,那么 A→C 就是传递依赖(A是候选键,B、C是非关键字段,C依赖B,B依赖A,所以C传递依赖A)。

比如上表:

1.只要 id 确定了,学号,姓名,年龄,性别,还有学院信息都明确了~~

那就是直接的依赖~~

2.但是关于学院电话和学院地址对于Id来说其实是传递依赖,

学院确定了,学院电话和学院地址就确定了~~

同学确定了,学院就确定了

这其实是--不科学的设计~~

四、总结

本篇博客记住几个点:

  • 范式是软性约定,不是语法硬规,日常到第三范式足够;

  • 第一范式抓“原子性”(列不可拆);

  • 第二范式抓“完全依赖”(消灭部分依赖,避免冗余和维护问题);

  • 第三范式抓“传递依赖”(进一步精简);

  • 实践出真知,写多了表自然能找到更优解~