关系数据库的去规范化(Denormalization)设计

目的:提升性能
去规范化会使实现变得更加复杂
逆规范化通常会降低灵活性
逆规范化会加快检索的速度,但却会降低更新的速度。(对数据库不需要经常更新,频繁检索的应用更合适!)

合并一对一联系

如果两个关系之间的联系是一对一,并且经常被一起访问,很少单独访问其中的一个关系,那就应该考虑合并

在一对多联系中复制非关键字属性以减少连接操作

将父关系的一个或者多个非关键字属性复制到一对多联系的子关系,以减少连接操作
在这里插入图片描述
因复制而产生的一个相关问题是每当一个元组被插入、修改或者删除时,会带来维持数据一致性的额外开销
因复制所带来的存储开销问题:目前二级存储器的价格很便宜,已不是一个很重要的问题,但这并不意味着可以随意复制

使用查看表(lookup table)
在这里插入图片描述
为房产类型定义一个查看表PropertyType(父关系),并将表PropertyForRent (子关系)修改为右边形式

使用查看表的好处

  • 减小子关系的大小:代码类型type属性只占1 个字节,而类型描述description属性需要5 个字节
  • 如果描述可能被修改(在本例子中不会),则只需要在查看表中修改一次,而不需要在子关系中修改多次
  • 查看表可以用来检查用户输入的有效性

如果将查看表用于频繁执行的查询或者关键查询中,并且描述属性一般不会被修改,则可以考虑将查看表的描述属性复制到子关系中。

在一对多联系中复制外键属性以减少连接操作

在多对多联系中复制属性以减少连接操作

每个多对多联系映射为了三个关系:由两个原始实体导出两个关系,另一个新关系则表示两个实体之间的联系。
如果希望从多对多联系中提取信息,就不得不将这三个关系连接起来。
某些情况下,将原实体中的属性复制到那个中间关系中,就可能减少参加连接操作的关系的个数。

引入重复组(减少因为多值属性所产生的连接)

一般来说,在下面的情况下可以考虑这种逆规范化:

  • 重复组中项的绝对数目是已知的(本例中最多有三个电话号码)
  • 该数目是静态的,不会随着时间的改变而改变(最多的电话号码个数是固定的,且不希望被改变) 。
  • 该数目不是很大,一般不会超过10(与前两个条件比起来,这个条件并不十分重要)

创建抽取表

  • 有些时候可能需要在白天的峰值时刻运行报表程序。
    • 报表程序可能会访问某些导出数据,要在同一组基础关系上运行涉及了多个关系的连接操作
    • 报表所需要的数据可能是相对静止的,或者在某些情况下可以不必是当前的
  • 比如说几个小时之前或者前一天的数据都不影响
    • 可以基于报表所需的关系表,创建一个独立的、高度去规范化的抽取表
    • 用户可以直接访问抽取表,而不必访问基础关系

常用的创建抽取表的方法是:在系统负载较轻时批量创建并装载这些表

对关系进行分区(Partition)

分区的好处

  • 改善负载平衡:各个分区可以被分配到二级存储器的不同区域,从而允许数据的并行访问。假设关系 没有被分区,则数据都存储在同一片区域,此时并行访问这片区域的数据的操作之间存在着竞争,关系的分区可将这种竞争最小化。
  • 提高性能:通过限制要访问和处理的数据量以及通过并行处理来提高系统性能。
  • 提高可用性:由于不同的分区存储在不同的区域,因此当一个存储区域不可用时,其他分区仍然可用
  • 提高可恢复性:小的分区可以更高效地恢复(DBA会发现备份小的分区比备份超大的关系更容易些) 。
  • 安全:对于分区中的数据,可以只允许需要访问它们的用户访问,不同的分区可以有不同的访问限制。

分区的坏处

  • 复杂:分区对于终端用户和查询并不总是透明的,执行写操作时,使用多于一个分区会更加复杂。
  • 降低性能:查询时,合并多个分区中的数据要比从没被分区的关系中获取数据慢。
  • 复制的影响:垂直分区要复制主关键字,这不仅会增加存储空间的大小,而且会增加潜在的不一致性。

去规范化设计的影响

需要重新考虑被去规范化的关系上索引的选择

  • 是否去掉某些现存的索引
  • 是否需要增加新的索引

需要考虑如何维护数据的完整性,常用的解决方法有:

  • 使用触发器,自动更新导出和复制的数据。
  • 在应用中使用事务,将被去规范化的数据的更新作为一个单一(原子)操作处理。
  • 完整性批处理:在适当的时候运行批处理程序维护去规范化数据的一致性

去规范化优缺点

发布了16 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_39938635/article/details/89597343