数据仓库设计 - 具有频繁变化的维度键的定期快照

Posted

技术标签:

【中文标题】数据仓库设计 - 具有频繁变化的维度键的定期快照【英文标题】:Data warehouse design - periodic snapshot with frequently changing dimension keys 【发布时间】:2018-09-08 15:40:12 【问题描述】:

想象一个事实表,其中包含一段时间内的度量总和,比如 1 小时。

Start Date          | Measure 1 | Measure 2
-------------------------------------------
2018-09-08 00:00:00 | 5         | 10
2018-09-08 00:01:00 | 12        | 20

理想情况下,我们希望保持每行正好是 1 小时的粒度。但是,每一行都引用了可能“破坏”纹理的尺寸。例如:

Start Date          | Measure 1 | Measure 2 | Dim 1
---------------------------------------------------
2018-09-08 00:00:00 | 5         | 10        | key 1
2018-09-08 00:01:00 | 12        | 20        | key 2

维度值可能会在 30 分钟后更改为一小时,在这种情况下,上述内容可能不准确,应如下表示:

Start Date          | Measure 1 | Measure 2 | Dim 1
---------------------------------------------------
2018-09-08 00:00:00 | 5         | 10        | val 1
2018-09-08 00:00:30 | 5         | 10        | val 2
2018-09-08 00:01:00 | 12        | 20        | val 2

在我们的场景中,数据需要通过至少 5 个维度键进行切片,查询如下:

sum(measure1) where dim1 = x and dim2 = y..

是否有针对此要求的设计模式?我考虑过“定期快照”,但我还没有读到任何关于这种在维度更改时进行行拆分的文章。

我只能看到两个选项:

    存储在每行中出现最多的维度值(例如,如果维度值在一小时内的大部分时间都为真,则使用该值)。这会导致一些准确性损失。 在每次维度更改时拆分每一行。这在 ETL 中很复杂,会创建更多数据并打破事实表中的粒度规则。

选项 2 是当前的解决方案,可以达到目的,但更难维护。有没有更好的方法或其他选择?

作为一个真实的例子,这个系统记录了制造环境中的生产数据,因此数据类似于:

Line   | Date                | Crew   | Product   | Running Time (mins)
-----------------------------------------------------------------------
Line 1 | 2018-09-08 00:00:00 | Crew A | Product A | 60

如前所述,人员、产品或任何其他维度可能在一小时内发生多次变化。

【问题讨论】:

我看到了一个有点类似的情况,它是由一个“暂存/当前”表和一个“事实/过去”表处理的。在您的情况下,根据报告需求和“工作完成”的定义,您可以保留两个表并将数据从第一个表“移动”到第二个表。这有意义吗? 谢谢,虽然不确定这是否是主要问题。我想关键问题是这样的:当维度键发生变化(从而混合颗粒)时拆分事实表中的行是否可以/正常,或者是否有更合适的模式? 【参考方案1】:

您不需要拆分事实表的时间部分,因为您显然想要报告每小时数据,但您应该有两条记录,一条用于每个维度值。如果这是事务事实表的聚合,则加载每小时表的过程应该按每个维度键对每条记录进行分组。所以在你上面的例子中,你应该有两个小时的记录,如下所示:

Start Date          | Measure 1 | Measure 2 | Dim 1
---------------------------------------------------
2018-09-08 00:00:00 | 5         | 10        | val 1
2018-09-08 00:01:00 | 5         | 10        | val 1
2018-09-08 00:01:00 | 12        | 10        | val 2

您还需要考虑其他措施,并确保它们都进入正确的存储桶(val 1 或 val 2)。我在示例中均分它们。

现在,如果您按小时 1 和 Dim 1 值 2 切片,您只会看到 12(测量 1),如果您按小时 1 切片,将 1 值 1 切片,您只会看到 5,如果您只在第 1 小时切片,您将看到 17。

请记住,您的粒度是由每个维度的级别定义的,而不仅仅是时间维度。 HTH。

【讨论】:

是的,我认为这就是我对“选项 2”的意图。不会像这样“拆分”行,但您会为每个维度值组合每小时生成一行。您的最后一句话是关键点:颗粒可以基于时间和维度值,因此这样做不会破坏颗粒。

以上是关于数据仓库设计 - 具有频繁变化的维度键的定期快照的主要内容,如果未能解决你的问题,请参考以下文章

数仓设计--维度(全量、拉链表)

数据仓库之事实表设计

聊聊数据仓库中的缓慢变化维度(SCD)

二数据仓库模型设计

二数据仓库模型设计

数据仓库设计:如何设计交货日期变化的事实和维度表