数据库三范式(1NF、2NF、3NF)

发布于:2024-11-03 ⋅ 阅读:(109) ⋅ 点赞:(0)

1NF(第一范式)

定义:确保每一列都是原子值,即是不可分割的基础数据项

所谓第一范式(1NF)是指在关系模型中,对于添加列的一个规范要求,所有的列都
应该是原子性的,即数据库表的每一列都是不可分割的原子数据项
,而不能是集合,
数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属
性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一
部分。简而言之,第一范式就是无重复的域。

比如地址,我们可以存为辽宁省大连市甘井子区。那么这样其实就不满足,因为我们
把省市区放在一起存储了。我们将地址进行拆分存储即可。省,市,区。这样满足
第一范式。

2NF(第二范式)

定义:在满足1NF的基础上,消除非主键字段对主键字段的部分(函数)依赖

部分函数依赖是指在一个关系表中,非主属性(即非主键字段)依赖于主键的一部分,而不是整个主键。在第二范式(2NF)中,要求非主属性必须完全依赖于主键,这意味着非主属性不能只依赖于主键的一部分。

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

部分函数依赖的例子:

假设Student表的结构如下:

学生编号 学生姓名 班级编号 院系 课程编号 成绩
S01 杨明 D01 思齐 C01 90
S02 李婉 D01 思齐 C01 87
S01 杨明 D01 思齐 C02 92
S03 刘海 D02 述圣 C01 95
S04 安然 D02 述圣 C02 78
S05 乐天 D03 省身 C01 82

复合主键是指由多个字段组合起来,共同作为表的主键,这些字段的组合值必须是唯一的,用来唯一标识表中的每条记录。

学生编号是作为识别学生的唯一标识,我们可以假设它是主键。但是,如果我们考虑到成绩是针对每个学生编号和课程编号组合的,那么在这个特定场景下,学生编号和课程编号一起构成了复合主键因为只有这两个字段的组合才能唯一确定一条记录。

部分函数依赖的情况是指在一个复合主键的情况下,非主属性依赖于主键的一部分。例如,如果学生姓名、班级编号和院系只依赖于学生编号而不依赖于课程编号,那么这些非主属性就对复合主键(学生编号,课程编号)存在部分函数依赖。

为了消除这种部分函数依赖,我们可以将表拆分成两个:

  1. 学生基本信息表(只包含学生编号、学生姓名、班级编号和院系):
学生编号 学生姓名 班级编号 院系
S01 杨明 D01 思齐
S02 李婉 D01 思齐
S03 刘海 D02 述圣
S04 安然 D02 述圣
S05 乐天 D03 省身
  1. 学生成绩表(包含学生编号、课程编号和成绩):
学生编号 课程编号 成绩
S01 C01 90
S02 C01 87
S01 C02 92
S03 C01 95
S04 C02 78
S05 C01 82

这样,每个表的非主属性都完全依赖于其主键,满足了第二范式(2NF)。

3NF(第三范式)

定义:在满足2NF的基础上,消除非主键字段对主键的传递依赖

第三范式(3NF):第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

举例说明:

上表中,所有属性都完全依赖于学号,所以满足第二范式,但是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,
而不是主键“学号”,所以需做如下调整:

这样以来,就满足了第三范式的要求。

不过现在业务上的表设计基本都是反范式的。当然不是说完全不遵守范式,而是适当的进行调整
比如业务上经常需要余字段,减少联表查询,提升性能,特别是业务量比较大的公司,这种冗余是很有必要的!


网站公告

今日签到

点亮在社区的每一天
去签到