数据库范式和反范式

数据库范式

第一范式(1NF)
第一范式要求数据库表的每一列都是不可分割的基本数据项,即表中的字段值必须是原子的、不可再分的。换句话说,表中的所有字段值都应该是单一的,而不是集合、数组或记录等复合数据类型。这是数据库设计中最基本的要求,任何关系型数据库都应该满足第一范式。

第二范式(2NF)
第二范式建立在第一范式的基础上,它要求表必须有一个主键,且表中的非主键列必须完全依赖于主键。所谓完全依赖,是指非主键列不能仅依赖于主键的一部分(比如主键是复合主键时)。如果表中存在部分依赖,则不满足第二范式,此时应该将表拆分为两个或多个表,以消除部分依赖。

第三范式(3NF)
第三范式建立在第二范式的基础上,它进一步要求表中的非主键列必须直接依赖于主键,而不能存在传递依赖。传递依赖是指非主键列依赖于另一个非主键列,而这个非主键列又依赖于主键。如果表中存在传递依赖,则不满足第三范式,这通常会导致数据冗余和更新异常。为了消除传递依赖,需要将表进一步拆分,使得每个表中的非主键列都直接依赖于主键。

第一范式,

列属性必须不可分割,(基础和绩效可以合并为工资列,但具体的工资可以抽出一张表独立维护)不能有小表存在。

学号 姓名 年龄 绩效 基础工资 邮箱
1111 张三 11 1344 12 zhangsan.@huawei.email
2222 李四 23 122 31 lisi.@huawei.email
3333 王五 44 444 144 wangwu.@huawei.email

合并工资后,可以对工资更加详尽的记录,

  1. 学生信息表,
学号 姓名 年龄 工资 邮箱
1111 张三 11 工资ID zhangsan.@huawei.email
2222 李四 23 工资ID lisi.@huawei.email
3333 王五 44 工资ID wangwu.@huawei.email

2.工资信息表,

工资ID 学号 基础工资 绩效 奖金 扣除工资
工资ID 1111 12112 11 233 222
工资ID 2222 1212 23 32 333
工资ID 3333 21212 44 1221 111

可以看出第一范式强调的是,存在小表就需要通过外间独立维护。

第二范式,

第一范式基础上,表中的非主属性必须完全依赖某一候选健。即,表中不能存在联合主键,不能有另外的表合并进主表,因为我们完全可以将成绩表合并给学生表从和实现成绩的查询。

学号 姓名 年龄 成绩 课程
1111 张三 11 99 数学
2222 李四 23 100 语文
3333 王五 44 40 英语

分解后

  1. 学生信息表,
学号 姓名 年龄
1111 张三 11
2222 李四 23
3333 王五 44

2,成绩表

学号 课程ID 成绩
1111 222 11
2222 111 23
3333 222 44

可以看出第二范式强调的是,存在的联合主键就说明可以独立维护成一张表。往往这张表是中间表,存储数据全是ID。

第三范式,

第二范式基础上,要求所有非主属性不依赖于其他非主属性。即,数据库中的每一列都可以由主键决定而不是其他列可以推导的。或者说数据库的每一列都和主属性直接相关,而不存在传递依赖。

学号 姓名 系主任 系名称
1111 张三 主任A 新闻系
2222 李四 主任B 语言系
3333 王五 主任C 历史系

其中系主任可以由系号推到而出,系号由学号推到而出。所以存在传递来,那就必须将系信息表独立维护了,

  1. 学生信息表,
学号 姓名 系ID
1111 张三 11
2222 李四 23
3333 王五 44

2,系信息表

系ID 系名称 系主任
1111 新闻系 李时珍
2222 历史系 王维
3333 语言系 李清照

BC范式

第三范式基础上,尽量避免数据冗余和不一致,提高可靠性和完整性

仓库ID 存储物品ID 管理员ID 数量
1111 2222 3131 1313
2222 1121 133 1331
3333 113331 13113 133

一个管理员只在一个仓库工作,一个仓库存在多个存储物品,该表满足第三范式,但是仍存在如下问题,

  • 异常删除, 当某仓库物被清空后,就需要将存储物品和管理员清除,其实这也顺带清楚了管理员和仓库之间的关系,真是系统中往往管理员是不会频繁改变的。 比如 小明管理仓库A。
  • 插入异常,反之亦然,当仓库没有货物时,无法建立仓库与管理员的关系。
  • 更新异常, 当仓库更换管理员时,所有相关的行记录都需要更新。

这就需要对表进行拆解,

  1. 仓库货物信息表
仓库ID 存储物品ID 数量
1111 2222 1313
2222 1121 1331
3333 113331 133
  1. 仓库管理员关联信息表
仓库ID 管理员ID
1111 2222
2222 1121
3333 113331

再看上述异常就会被消除,当删除货物时,管理员信息保持独立,当插入管理员和仓库信息时,无需货物信息存在,当更新管理员信息时,货物表不受影响。

第五范式

第五范式(5NF)也被称为完美范式。它要求关系模式R的依赖关系完全由R的候选码所隐含,即属性均为候选码。第五范式旨在通过分隔语义连接的关系来存储多值事实,以减少关系数据库中的冗余。

在实际应用中,第五范式的应用较少,因为它涉及到复杂的表分解和重组,可能会导致查询变得更加复杂。然而,在一些特定情况下,第五范式仍然有其价值。例如,在一个大型复杂的数据库系统中,存在大量的关系模式和数据依赖关系,通过使用第五范式,可以更好地管理和维护这些复杂的数据模型,并提高数据库系统的性能和可靠性。

总的来说,第五范式是一种高级形式的实体完整性,可以帮助数据库系统更好地管理和维护大型复杂的数据模型。尽管它在日常使用中不如第三范式常见,但它在处理特定类型的数据模型时仍然非常有用。

反范式

数据库范式的本质是规范化,通过规范化可以有效的避免一些冗余甚至是一些错误的产生。
然而,真实的环境中往往不是完美的规范,或者说遵循完美不一定是正确的。真实的场景中,客户或者系统是需要关注性能的,所以就需要反规范化的一些设计去提升性能,这也就是为什么会有反范式的存在。

通过合理的反范式设计,可以有效地

  • 降低连接操作的需求
  • 降低外键和索引的数目
  • 减少表的数目

从而提高查询效率。

反范式的方法

  1. 增加冗余列:再多个表中,都增加相同的列,从而避免获取某些信息时的连表操作。
  2. 增加派生列:在表中增加可以由别的表计算而来的列。
  3. 重新组表:如果两张表经常需要连接在一些查看所有内容,则将两张表合并为一张大表。
  4. 水平分割:数据规模过大时,可以将同一张表的数据分隔开存放在不同的表(Student1,Student2,Student3,)中。
  5. 垂直分割:对于列过多的表,将不同列分割到不同的表中,主键串联两张表。(student, student_extend)

带来的其他问题

  1. 数据冗余:反范式设计会引入冗余数据,这可能会导致数据不一致性和数据更新时的额外开销。
  2. 更新异常:当修改反范式表中的数据时,可能需要在多个地方进行修改,这可能会导致更新异常。
  3. 存储空间浪费:反范式会引入冗余数据,因此可能会浪费存储空间。
  4. 查询性能提升有限:在数据量小的情况下,反范式不能体现性能的优势,可能还会让数据库的设计更加复杂。
  5. 维护成本增加:由于数据冗余,数据维护成本更高,特别是在需要更新大量冗余数据时。

反范式缺点的解决方案

然而,反范式设计可能会引入数据冗余,导致数据不一致性和数据更新时的额外开销。以下是针对反范式设计缺点的解决方案:

  • 数据清洗:定期进行数据清洗,以确保数据的准确性和一致性。这包括识别和纠正错误数据、去除重复数据等。

  • 数据同步机制:建立有效的数据同步机制,确保所有冗余数据在更新时都能及时反映变化。

  • 索引优化:通过合理的索引设计,减少查询时需要扫描的数据量,提高查询效率。

  • 分区和归档:对于历史数据,可以进行分区和归档处理,以减少对当前数据的影响。

  • 事务隔离:在处理冗余数据时,确保事务隔离级别足够高,防止数据不一致。

  • 监控和报警:实施实时监控,一旦检测到数据不一致,立即发出警报并采取措施。

  • 数据治理:建立健全数据治理体系,制定明确的数据管理政策和流程,确保数据的质量和安全。

总结

范式
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容