我一直认为数据库应该针对读取性能进行非规范化,因为它是针对OLAP数据库设计完成的,并没有为OLTP设计进一步夸大3NF。
在Performance of different aproaches to time-based data中的各种帖子中的PerformanceDBA捍卫了数据库应该始终通过归一化到5NF和6NF(普通形式)来精心设计的范例。
我是否理解正确(以及我理解的是什么)?
OLAP数据库(低于3NF)的传统非规范化方法/范例设计有什么问题?对于大多数OLTP数据库的实际情况,3NF的建议是否足够?
例如:
我应该承认,我永远无法理解非规范化有助于读取性能的理论。任何人都可以给我参考,对这个和相反的信念有合理的解释吗?
在尝试说服我的利益相关者说OLAP / Data Warehousing数据库应该规范化时,我可以参考哪些来源?
为了提高我在评论中复制的可见性:
“如果参与者愿意的话会很好 添加(披露)有多少现实生活(没有 包括科学项目) 6NF中的数据仓库实现 他们已经看过或参与过。 快速游泳池。我= 0.“ - 达米尔 Sudarevic
Wikipedia's Data Warehouse article告诉:
“规范化的方法[与Ralph Kimball的尺寸1]也是如此 称为支持者的 3NF模型(第三范式) 被称为“Inmonites”,相信Bill Inmon的做法 据说数据仓库应使用E-R建模 模型/标准化模型。“
看起来规范化的数据仓库方法(Bill Inmon)被认为不超过3NF(?)
我只是想了解数据仓库/ OLAP是非规范化的同义词的神话(或无处不在的公理信念)的起源是什么?
达米尔苏达雷维奇回答说他们铺好了道路。让我回到这个问题:为什么反规范化被认为有助于阅读?答案 0 :(得分:136)
答案 1 :(得分:8)
非规范化和聚合是用于在数据仓库中实现性能的两个主要策略。建议它不会提高读取性能是愚蠢的!当然,我一定在这里误解了什么?
<强>聚合:强> 考虑一个持有10亿购买的表。 将其与持有一行的表格进行对比。 现在哪个更快?从十亿行表中选择总和(金额)还是从一行表中选择金额?这当然是一个愚蠢的例子,但它很清楚地说明了聚合的原理。为什么它更快?因为无论我们使用什么神奇的模型/硬件/软件/宗教,读取100字节比读取100千兆字节更快。就这么简单。
<强>非规范化:强> 零售数据仓库中的典型产品维度具有大量列。有些列很简单,比如“Name”或“Color”,但它也有一些复杂的东西,比如层次结构。多个层次结构(产品范围(5个级别),预期买方(3个级别),原材料(8个级别),生产方式(8个级别)以及几个计算数字,例如平均提前期(自年初以来) ,重量/包装措施etcetera etcetera。我维护了一个200多列的产品维度表,它是由来自5个不同源系统的约70个表构建的。讨论是否对规范化模型进行查询(下图)是很愚蠢的
select product_id
from table1
join table2 on(keys)
join (select average(..)
from one_billion_row_table
where lastyear = ...) on(keys)
join ...table70
where function_with_fuzzy_matching(table1.cola, table37.colb) > 0.7
and exists(select ... from )
and not exists(select ...)
and table20.version_id = (select max(v_id from product_ver where ...)
and average_price between 10 and 20
and product_range = 'High-Profile'
...比非规范化模型上的等效查询更快:
select product_id
from product_denormalized
where average_price between 10 and 20
and product_range = 'High-Profile';
为什么呢?部分出于与聚合场景相同的原因。但也因为查询只是“复杂”。它们非常令人厌恶,以至于优化器(现在我正在使用Oracle的细节)变得困惑并搞砸了执行计划。如果查询处理少量数据,则次优执行计划可能不是那么重要。但是一旦我们开始加入大表,那么数据库就可以正确地获得执行计划至关重要。使用单个同步密钥对一个表中的数据进行非规范化(哎呀,为什么我不为这个正在进行的火灾添加更多燃料),过滤器成为预先制作的列上的简单范围/相等过滤器。将数据复制到新列使我们能够收集有关列的统计信息,这将有助于优化器估计选择性,从而为我们提供正确的执行计划(好吧......)。
显然,使用非规范化和聚合使得更难以适应模式更改这是一件坏事。另一方面,它们提供了读取性能,这是一件好事。
那么,您是否应该对数据库进行非规范化以实现读取性能? 一定不行!它为您的系统增加了许多复杂性,以至于在您交付之前,它将以多少方式阻止您。这值得么?是的,有时您需要这样做以满足特定的性能要求。
更新1
PerformanceDBA:1行将每天更新10亿次
这意味着(接近)实时要求(反过来会产生一组完全不同的技术要求)。许多(如果不是大多数)数据仓库没有这个要求。我选择了一个不切实际的聚合示例,只是为了明确聚合的工作原理。我也不想解释汇总策略:)
此外,必须对比数据仓库的典型用户和底层OLTP系统的典型用户的需求。如果有50%的当前数据丢失,或者10辆卡车爆炸并导致司机死亡,那么用户希望了解哪些因素会降低运输成本。进行2年以上数据分析仍然可以得出相同的结论,即使他必须掌握第二时间的最新信息。
将此与卡车司机(幸存者)的需求进行对比。他们不能在某个转接点等待5个小时,因为一些愚蠢的聚合过程必须芬兰语。拥有两个独立的数据副本可以满足这两种需求。
为操作系统和报告系统共享同一组数据的另一个主要障碍是发布周期,Q&amp; A,部署,SLA以及您拥有的内容是非常不同的。同样,有两个单独的副本使这更容易处理。
答案 2 :(得分:6)
通过“OLAP”我理解你是指用于决策支持的面向主题的关系/ SQL数据库 - AKA是一个数据仓库。
普通表格(通常为第5 /第6范式)通常是数据仓库的最佳模型。规范化数据仓库的原因与任何其他数据库完全相同:它减少了冗余并避免了潜在的更新异常;它避免了内置偏差,因此是支持模式更改和新要求的最简单方法。在数据仓库中使用Normal Form还有助于保持数据加载过程的简单和一致。
没有“传统的”非规范化方法。好的数据仓库一直都是标准化的。
答案 3 :(得分:5)
数据库不应该为了读取性能而非规范化吗?
好的,这里有一个“你的里程可能会变化”,“它取决于”,“为每个工作使用适当的工具”,“一个尺寸不适合所有”的答案,有点“不要修复如果它没有破碎“投入:
非规范化是在某些情况下提高查询性能的一种方法。在其他情况下,它实际上可能会降低性能(因为磁盘使用量增加)。它肯定会使更新变得更加困难。
只有当您遇到性能问题时才应该考虑它(因为您正在提供规范化的好处并引入复杂性)。
对于永不更新的数据,或仅在批处理作业中更新的数据,即非OLTP数据,非规范化的缺点不是问题。
如果非规范化解决了您需要解决的性能问题,并且侵入性较小的技术(如索引或缓存或购买更大的服务器)无法解决,那么是的,您应该这样做。
答案 4 :(得分:3)
答案 5 :(得分:2)
构建数据仓库(DW)的两种最流行的方法似乎是Bill Inmon和Ralph Kimball。
Inmon的方法使用标准化方法,而Kimball使用维度建模 - 去标准化的星型模式。
两者都有很好的文档记录到细节,并且都有许多成功的实现。两者都为DW目的地提供了“宽阔,铺设良好的道路”。
我不能评论6NF方法和Anchor Modeling,因为我从未见过或参与过使用该方法的DW项目。在实现方面,我喜欢沿着经过良好测试的路径旅行 - 但是,这只是我。
总而言之,DW应该归一化还是去规范化?取决于您选择的方法 - 只需选择一个并坚持下去,至少直到项目结束。
编辑 - 示例
在我目前工作的地方,我们有一份遗留报告,它一直在生产服务器上运行。不是一份简单的报告,而是每天通过电子邮件发送给每个人和他的蚂蚁的30份子报告。
最近,我们实施了DW。有两个报表服务器和一堆报告,我希望我们可以忘记遗留的事情。但不是,遗产是遗产,我们总是拥有它,所以我们想要它,需要它,不能没有它等等。
问题是python脚本和SQL的混乱需要花费8个小时(是的,e-i-g-h-t小时)来运行每一天。毋庸置疑,数据库和应用程序是由少数开发人员多年建立的 - 所以,不完全是你的5NF。
是时候从DW重新创建传统的东西了。好吧,为了做到这一点,它已经完成了,需要3分钟(t-h-r-e-e分钟)来制作它,每个子报告需要6秒钟。而且我急于交付,所以甚至没有优化所有查询。这是8 * 60/3 = 160倍的因素 - 更不用说从生产服务器中删除8小时作业的好处了。我想我仍然可以刮一分钟左右,但现在没有人关心。
作为一个兴趣点,我使用了Kimball的方法(维度建模)用于DW,这个故事中使用的所有内容都是开源的。
我认为这就是所有这些(数据仓库)应该是什么。是否使用了哪种方法(标准化或非标准化)?
编辑2
作为一个兴趣点,Bill Inmon在他的网站上有一篇写得很好的论文 - A Tale of Two Architectures 。
答案 6 :(得分:2)
“非规范化”这个词的问题在于它没有指明要进入的方向。这就像试图从纽约开车去旧金山一样。
星型模式或雪花模式肯定没有规范化。在某些使用模式中,它肯定比标准化模式表现更好。但是有一些非规范化的情况,设计师根本没有遵循任何规则,只是凭直觉组成表格。有时这些努力并没有成功。
简而言之,不要只是反规范化。如果您对其好处充满信心,即使它不符合标准化设计,也要遵循不同的设计规则。但是不要使用非规范化作为随意设计的借口。
答案 7 :(得分:1)
简短的回答是不能修复你没有的性能问题!
对于基于时间的表,普遍接受的pardigm是在每一行中都有valid_from和valid_to日期。这基本上仍然是3NF,因为它只将语义从“这是这个实体的唯一一个版本”更改为“这是此实体的唯一版本此时”
答案 8 :(得分:1)
简化:
应该对OLTP数据库进行规范化(只要有意义)。
应将OLAP数据仓库非规范化为Fact和Dimension表(以最小化连接)。