什么时候应该非规范化?

Ric*_*ard 49 database-design

我想我们都熟悉数据库规范化

我的问题是:当您想对表进行非规范化时,您使用哪些准则?

bil*_*nkc 37

在 OLAP 操作时进行非规范化,在 OLTP 时进行规范化(来自非规范化部分下的链接文章)

用于联机事务处理 (OLTP) 的数据库通常比用于联机分析处理 (OLAP) 的数据库更规范化。OLTP 应用程序的特点是大量小额交易,例如在超市收银台更新销售记录。期望每个事务都会使数据库处于一致状态。相比之下,用于 OLAP 操作的数据库主要是“主要读取”数据库。OLAP 应用程序倾向于提取长期积累的历史数据。对于此类数据库,冗余或“非规范化”数据可以促进商业智能应用。具体来说,星型模式中的维度表通常包含非规范化数据。在提取、转换、加载 (ETL) 处理期间必须仔细控制非规范化或冗余数据,并且在数据处于一致状态之前不应允许用户查看数据。星型模式的标准化替代方案是雪花模式。在许多情况下,随着计算机和 RDBMS 软件变得更加强大,对非规范化的需求已经减弱,但由于数据量通常随着硬件和软件性能而增加,因此 OLAP 数据库通常仍然使用非规范化模式。

非规范化还用于提高小型计算机的性能,如计算机化收银机和移动设备,因为它们可能仅将数据用于查找(例如价格查找)。当平台(例如 Palm)不存在 RDBMS 或不对数据进行任何更改并且快速响应至关重要时,也可以使用非规范化。

  • 我在创建报告或分析时进行非规范化,我想要快速的结果。世界上所有具有多个连接的索引都不会像表示不会更改的缓存数据的非规范化表那样快。 (5认同)

And*_*nea 27

规范化直到它受到伤害,非规范化直到它起作用(即:性能变得可以接受):)

  • 这可能不是最好的答案,但它是我在 Stack Overflow 上看到的最好的单行代码之一:) (9认同)

nvo*_*gel 17

应用受控非规范化的一个潜在合理原因是,如果它使您能够对数据应用某些原本不可能实现的完整性约束。大多数 SQL DBMS 对多表约束的支持极其有限。在 SQL 中,有时实现某些约束的唯一有效方法是确保约束中涉及的属性都存在于同一个表中——即使规范化规定它们属于不同的表。

受控非规范化意味着实施机制以确保不会因冗余数据而出现不一致。在决定非规范化是否值得时,需要考虑这些额外控制的成本和数据不一致的风险。

非规范化的另一个常见原因是允许对存储结构进行一些更改或允许进行其他一些 DBMS 不允许的物理优化。根据物理数据独立性原则,DBMS 应该能够配置内部存储结构,而无需不必要地改变数据库中数据的逻辑表示。不幸的是,许多 DBMS 对任何给定数据库模式可用的物理实现选项都非常严格。他们倾向于通过仅支持所需逻辑模型的次优实现来损害物理数据库的独立性。

这应该是显而易见的,但仍然需要说明:在所有情况下,只有物理实现特性的变化才能决定性能——诸如内部数据结构、文件、索引、硬件等特性。规范化和非规范化与性能或存储优化无关。


Nic*_*mas 5

如果您经常访问计算数据,请按照此问题的答案中的建议进行非规范化。如果您的负载配置文件是大量读取的,那么存储和维护计算数据的成本通常会低于一遍又一遍地重新计算数据的成本。


A-K*_*A-K 5

我经常进行非规范化,以便我可以通过约束来强制执行数据完整性。一个例子是这个站点上最近的一个问题- 我在另一个表中复制一列,以便我可以使用CHECK约束将它与另一列进行比较。这种技术的另一个例子是我的博客文章

你不能使用 CHECK约束来比较不同行或不同表中的列,除非您将此类功能包装在从CHECK约束调用的标量 UDF 中。如果您确实需要比较不同行或不同表中的列以强制执行业务规则,该怎么办?

例如,假设您知道一位医生的工作时间,并且您想确保所有预约都在工作时间内?当然,您可以使用触发器或存储过程来实现此业务规则,但是触发器和存储过程都不能给您 100% 的保证您的所有数据都是干净的——有人可以禁用或删除您的触发器,输入一些脏数据,并重新启用或重新创建触发器。也有人可以绕过存储过程直接修改您的表。无论哪种方式,您最终都可能在不知情的情况下得到违反业务规则的数据。

让我演示如何仅使用 FK 和 CHECK约束——只要所有约束都是可信的,就可以保证所有数据都满足业务规则。

另一个例子是一种强制时间段没有间隙和重叠的方法