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 |
复合主键是指由多个字段组合起来,共同作为表的主键,这些字段的组合值必须是唯一的,用来唯一标识表中的每条记录。
学生编号是作为识别学生的唯一标识,我们可以假设它是主键。但是,如果我们考虑到成绩是针对每个学生编号和课程编号组合的,那么在这个特定场景下,学生编号和课程编号一起构成了复合主键,因为只有这两个字段的组合才能唯一确定一条记录。
部分函数依赖的情况是指在一个复合主键的情况下,非主属性依赖于主键的一部分。例如,如果学生姓名、班级编号和院系只依赖于学生编号而不依赖于课程编号,那么这些非主属性就对复合主键(学生编号,课程编号)存在部分函数依赖。
为了消除这种部分函数依赖,我们可以将表拆分成两个:
- 学生基本信息表(只包含学生编号、学生姓名、班级编号和院系):
学生编号 | 学生姓名 | 班级编号 | 院系 |
---|---|---|---|
S01 | 杨明 | D01 | 思齐 |
S02 | 李婉 | D01 | 思齐 |
S03 | 刘海 | D02 | 述圣 |
S04 | 安然 | D02 | 述圣 |
S05 | 乐天 | D03 | 省身 |
- 学生成绩表(包含学生编号、课程编号和成绩):
学生编号 | 课程编号 | 成绩 |
---|---|---|
S01 | C01 | 90 |
S02 | C01 | 87 |
S01 | C02 | 92 |
S03 | C01 | 95 |
S04 | C02 | 78 |
S05 | C01 | 82 |
这样,每个表的非主属性都完全依赖于其主键,满足了第二范式(2NF)。
3NF(第三范式)
定义:在满足2NF的基础上,消除非主键字段对主键的传递依赖。
第三范式(3NF):第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
举例说明:
上表中,所有属性都完全依赖于学号,所以满足第二范式,但是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,
而不是主键“学号”,所以需做如下调整:
这样以来,就满足了第三范式的要求。
不过现在业务上的表设计基本都是反范式的。当然不是说完全不遵守范式,而是适当的进行调整。
比如业务上经常需要余字段,减少联表查询,提升性能,特别是业务量比较大的公司,这种冗余是很有必要的!