平面表的红移性能与维度和事实
Redshift Performance of Flat Tables Vs Dimension and Facts
我正在尝试在平面 OLTP tables(不在 3NF 中)上创建维度模型。
有些人认为维度模型 table 不是必需的,因为报告的大部分数据都是单一的 table。但是 table 包含的内容比我们需要的要多,比如 300 列。我还是应该将平面 table 分为维度和事实,还是直接在报告中使用平面 table。
当纯粹为了 报告目的 创建 table 时(这在数据仓库中很典型),通常会创建 宽、扁平tables 具有非规范化数据,因为:
- 查询更方便
- 它避免了可能使临时用户感到困惑和容易出错的 JOIN
- 查询 运行 更快(特别是对于使用 列式数据存储 的数据仓库系统)
这种数据格式非常适合报告,但不适合table用于应用程序的正常数据存储 — 用于 OLTP 的数据库应该使用规范化 tables.
不要担心大量的列——这对于数据仓库来说是很正常的。然而,300 列听起来确实很大,这表明它们未必被明智地使用。因此,您可能需要检查它们是否是必需的。
许多列的一个很好的例子是拥有使编写 WHERE 子句变得容易的标志,例如 WHERE customer_is_active
而不是必须连接到另一个 table 并弄清楚它们是否已使用过去 30 天内的服务。这些列需要每天重新计算,但查询数据非常方便。
底线:使用数据仓库时,您应该将易用性置于性能之上。然后,找出如何通过使用旨在非常有效地处理此类数据的数据仓库系统(例如 Amazon Redshift)来优化访问。
你问了一个关于数据仓库的数据库建模的一般性问题,它会为你提供可能不适用于你正在使用的数据库平台的一般性答案 - 如果你想要你正在使用的答案能够使用然后我建议更具体。
问题标签表明您正在使用 Amazon Redshift,并且该数据库的答案不同于 SQL Server 和 Oracle 等传统关系数据库。
首先您需要了解 Redshift 与常规关系数据库的不同之处:
1) 它是一个 Massively Parallel 处理 (MPP) 系统,由一个或多个节点组成,数据分布在这些节点上,每个节点通常完成回答每个查询所需的一部分工作。因此,数据在节点之间的分布方式变得很重要,目的通常是让数据以相当均匀的方式分布,以便每个节点为每个查询做大约相同数量的工作。
2) 数据存储在columnar format中。这与 SQL Server 或 Oracle 的基于行的格式完全不同。在列式数据库中,数据的存储方式使大型聚合类型查询更加高效。这种存储方式部分否定了维度tables的原因,因为按行存储重复数据(属性)相对高效。
Redshift tables 通常使用 one 列(分布键)的值分布在节点上。或者,它们可以随机但均匀分布,或者 Redshift 可以在每个节点上制作完整的数据副本(通常只用非常小的 tables 完成)。
因此,在决定是否创建维度时,您需要考虑这是否真的会带来很多好处。如果数据中有定期更新的列,那么最好将它们放在另一个较小的 table 中,而不是更新一个较大的 table。但是,如果数据主要是仅附加(不变)的,那么创建维度就没有任何好处。对数据进行分组和聚合的查询将在单个 table 上变得高效。
JOIN 在 Redshift 上可能会变得非常昂贵,除非两个 tables 分布在相同的值上(例如用户 ID)——如果它们不是,Redshift 将不得不在节点周围物理复制数据以成为能够运行查询。所以如果你必须有维度,那么你会想要将最大的维度 table 分布在与事实 table 相同的键上(记住每个 table 只能分布在一个列),那么任何其他维度可能需要作为 ALL 分布(复制到每个节点)。
我的建议是坚持使用单个 table,除非您迫切需要创建维度(例如,如果有列经常更新)。
我正在尝试在平面 OLTP tables(不在 3NF 中)上创建维度模型。
有些人认为维度模型 table 不是必需的,因为报告的大部分数据都是单一的 table。但是 table 包含的内容比我们需要的要多,比如 300 列。我还是应该将平面 table 分为维度和事实,还是直接在报告中使用平面 table。
当纯粹为了 报告目的 创建 table 时(这在数据仓库中很典型),通常会创建 宽、扁平tables 具有非规范化数据,因为:
- 查询更方便
- 它避免了可能使临时用户感到困惑和容易出错的 JOIN
- 查询 运行 更快(特别是对于使用 列式数据存储 的数据仓库系统)
这种数据格式非常适合报告,但不适合table用于应用程序的正常数据存储 — 用于 OLTP 的数据库应该使用规范化 tables.
不要担心大量的列——这对于数据仓库来说是很正常的。然而,300 列听起来确实很大,这表明它们未必被明智地使用。因此,您可能需要检查它们是否是必需的。
许多列的一个很好的例子是拥有使编写 WHERE 子句变得容易的标志,例如 WHERE customer_is_active
而不是必须连接到另一个 table 并弄清楚它们是否已使用过去 30 天内的服务。这些列需要每天重新计算,但查询数据非常方便。
底线:使用数据仓库时,您应该将易用性置于性能之上。然后,找出如何通过使用旨在非常有效地处理此类数据的数据仓库系统(例如 Amazon Redshift)来优化访问。
你问了一个关于数据仓库的数据库建模的一般性问题,它会为你提供可能不适用于你正在使用的数据库平台的一般性答案 - 如果你想要你正在使用的答案能够使用然后我建议更具体。
问题标签表明您正在使用 Amazon Redshift,并且该数据库的答案不同于 SQL Server 和 Oracle 等传统关系数据库。
首先您需要了解 Redshift 与常规关系数据库的不同之处:
1) 它是一个 Massively Parallel 处理 (MPP) 系统,由一个或多个节点组成,数据分布在这些节点上,每个节点通常完成回答每个查询所需的一部分工作。因此,数据在节点之间的分布方式变得很重要,目的通常是让数据以相当均匀的方式分布,以便每个节点为每个查询做大约相同数量的工作。
2) 数据存储在columnar format中。这与 SQL Server 或 Oracle 的基于行的格式完全不同。在列式数据库中,数据的存储方式使大型聚合类型查询更加高效。这种存储方式部分否定了维度tables的原因,因为按行存储重复数据(属性)相对高效。
Redshift tables 通常使用 one 列(分布键)的值分布在节点上。或者,它们可以随机但均匀分布,或者 Redshift 可以在每个节点上制作完整的数据副本(通常只用非常小的 tables 完成)。
因此,在决定是否创建维度时,您需要考虑这是否真的会带来很多好处。如果数据中有定期更新的列,那么最好将它们放在另一个较小的 table 中,而不是更新一个较大的 table。但是,如果数据主要是仅附加(不变)的,那么创建维度就没有任何好处。对数据进行分组和聚合的查询将在单个 table 上变得高效。
JOIN 在 Redshift 上可能会变得非常昂贵,除非两个 tables 分布在相同的值上(例如用户 ID)——如果它们不是,Redshift 将不得不在节点周围物理复制数据以成为能够运行查询。所以如果你必须有维度,那么你会想要将最大的维度 table 分布在与事实 table 相同的键上(记住每个 table 只能分布在一个列),那么任何其他维度可能需要作为 ALL 分布(复制到每个节点)。
我的建议是坚持使用单个 table,除非您迫切需要创建维度(例如,如果有列经常更新)。