Database OLAP数据库是否应该进行非规范化以提高读取性能?

Database OLAP数据库是否应该进行非规范化以提高读取性能?,database,database-design,data-modeling,olap,data-warehouse,Database,Database Design,Data Modeling,Olap,Data Warehouse,我一直认为数据库应该进行非规范化以提高读取性能,就像OLAP数据库设计一样,而不是进一步夸大OLTP设计的3NF 例如,PerformanceDBA在不同的岗位上都有出色的表现,它捍卫了数据库应该通过规范化为5NF和6NF(标准形式)来进行良好设计的范例 我是否正确理解了它(以及我正确理解了什么) OLAP数据库的传统非规范化方法/范式设计(低于3NF)和3NF对于OLTP数据库的大多数实际情况已经足够的建议有什么错 例如: 我应该承认,我永远无法理解非规范化有助于阅读性能的理论。有人能给

我一直认为数据库应该进行非规范化以提高读取性能,就像OLAP数据库设计一样,而不是进一步夸大OLTP设计的3NF

例如,PerformanceDBA在不同的岗位上都有出色的表现,它捍卫了数据库应该通过规范化为5NF和6NF(标准形式)来进行良好设计的范例

我是否正确理解了它(以及我正确理解了什么)

OLAP数据库的传统非规范化方法/范式设计(低于3NF)和3NF对于OLTP数据库的大多数实际情况已经足够的建议有什么错

例如:

我应该承认,我永远无法理解非规范化有助于阅读性能的理论。有人能给我一些关于这一点和相反观点的逻辑解释吗

当我试图说服利益相关者OLAP/数据仓库数据库应该规范化时,我可以参考哪些来源

为了提高可视性,我从评论中复制了以下内容:


“如果参与者能够 添加(披露)多少真实生活(否) (包括科学项目) 6NF中的数据仓库实现 他们看过或参加过。 有点快。我=0。”–达米尔 苏达雷维奇

说明:

“标准化方法[vs.Ralph Kimball的一维方法],也 被称为3NF模型(第三范式),其支持者是 被称为“Inmonite”,相信Bill Inmon的方法 数据仓库应该使用E-R建模 模型/规范化模型。”

看起来规范化数据仓库方法(Bill Inmon)被认为不超过3NF(?)

我只是想了解数据仓库/OLAP是非规范化同义词的神话(或普遍存在的公理信念)的起源是什么

达米尔·苏达雷维奇(Damir Sudarevic)回答说,这是一条很好的道路。让我回到问题上来:为什么非规范化被认为有助于阅读

简单的回答是,不要修复您尚未解决的性能问题

对于基于时间的表格,普遍接受的pardigm是在每一行中都有有效的起始日期和截止日期。这基本上仍然是3NF,因为它只是将语义从“这是该实体的唯一验证”更改为“这是该实体在此时的唯一版本”

数据库不应该为读取性能而非规范化吗

好的,这里有一个总的“你的里程数可能会有所不同”,“这取决于”,“在每项工作中使用合适的工具”,“一种尺寸不适合所有人”的答案,并加上一点“如果它没有坏,就不要修它”:

在某些情况下,反规范化是提高查询性能的一种方法。在其他情况下,它实际上可能会降低性能(因为磁盘使用量增加)。这无疑使更新更加困难

只有在遇到性能问题时才应该考虑它(因为您提供了规范化的好处并引入了复杂性)

非规范化的缺点是,对于从不更新或仅在批处理作业中更新的数据(即不是OLTP数据),问题较少

如果非规范化解决了您需要解决的性能问题,而非侵入性技术(如索引或缓存或购买更大的服务器)无法解决,那么您应该这样做。

简化:

OLTP数据库应该正常化(只要合理)

OLAP数据仓库应该被非规范化为事实表和维度表(以最小化联接)。

我理解“OLAP”是指用于决策支持的面向主题的关系型/SQL数据库,也称为数据仓库

范式(通常为第5/6范式)通常是数据仓库的最佳模型。规范化数据仓库的原因与任何其他数据库完全相同:它减少了冗余并避免了潜在的更新异常;它避免了内置的偏见,因此是支持模式更改和新需求的最简单方法。在数据仓库中使用标准表单也有助于保持数据加载过程的简单性和一致性


没有“传统”的非规范化方法。好的数据仓库一直都是标准化的。

构建数据仓库(DW)的两种最流行的方法似乎是Bill Inmon和Ralph Kimball

Inmon的方法使用规范化方法,而Kimball的方法使用维度建模——非规范化的星型模式

两者都有详细的文档记录,都有许多成功的实现。两者都为DW目的地提供了一条“宽阔、铺砌良好的道路”

我不能对6NF方法或锚建模发表评论,因为我从未见过也没有参与使用该方法的DW项目。说到实现,我喜欢沿着经过良好测试的路径前进——但是,这只是我自己

总之,DW应该规范化还是非规范化?取决于你选择的方法——只需选择一种并坚持下去,至少要坚持到项目结束

编辑-示例

在我目前工作的地方,我们有一个遗留报告,从那时起一直在生产服务器上运行。不是一个简单的报告,而是每天通过电子邮件发送给每个人和他的蚂蚁的30个子报告的集合

最近,我们实现了一个DW。有了两个报表服务器和一堆报表,我希望我们可以忘记遗留问题。但不是,遗产就是遗产,我们一直都有它,所以我们想要它,需要它,不能没有它,等等

问题是,一个混乱的python脚本和SQL每天要运行八个小时(是的,e-i-g-h-t小时)。不用说,数据库和应用程序是几年前建立的
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';
account_balances(month, report)
CREATE TABLE `t` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `member_id` int(10) unsigned NOT NULL,
  `status` tinyint(3) unsigned NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  `opening` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `member_id` (`member_id`),
  CONSTRAINT `t_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `m` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB

CREATE TABLE `m` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB
mysql> select sql_no_cache m.name, count(*) 
       from t join m on t.member_id = m.id 
       where t.id between 100000 and 500000 group by m.name;
+-------+----------+
| name  | count(*) |
+-------+----------+
| omega |       11 |
| test  |        8 |
| test3 |   399982 |
+-------+----------+
3 rows in set (1.08 sec)
alter table t add column varchar(255);
update t inner join m on t.member_id = t.id set t.name = m.name;
mysql> select sql_no_cache name, count(*) 
       from t where id 
       between 100000 and 500000 
       group by name;
+-------+----------+
| name  | count(*) |
+-------+----------+
| omega |       11 |
| test  |        8 |
| test3 |   399982 |
+-------+----------+
3 rows in set (0.41 sec)