我对事实表粒度的理解正确吗?


8

我自己和我们公司的另一个DBA的任务是审查供应商为我们开发的数据库设计。该供应商表示,他们使用Kimball作为其设计的基础。(注意:我不是在寻找Kimball与Inmon等的论点。)他们设计了一个具有多个事实和维度的集市。

公平地说,我们公司从未设计过一个集市。我们一直都有顾问来做。而且我们从未上过课。因此,我们对仓储/超市/维度建模等的了解是基于我们的经验不足,可以在互联网上找到的内容以及自我阅读(我们拥有Inmon和Kimball的书,并正在努力通过它们进行学习) 。

现在已经为我的知识水平奠定了基础,现在我们来应对设计挑战。

有一个称为“索赔损失统计”的事实表(用于保险)。他们正在尝试同时获取索赔的付款(累计到每月水平),然后是准备金中的钱(类似于用于索赔的银行帐户)。他们希望看到每月的付款金额(没什么大不了的)。但是他们希望看到该帐户当前的准备金余额。

我将给出一个图片示例。

假设我们为索赔设置了1000美元的储备金。这被搁置了(因此在某些方面它的功能有点像银行帐户)。

在2014年10月,我们尚未支付任何款项。因此,该公司希望在10月底看到付款和储备金余额。

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------

然后十一月来了。我们会分别支付$ 100,$ 150和$ 75美元。他们希望看到这些总额,余额中的准备金如下:

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------
-      112014  -    325.00 -           675.00 -
-----------------------------------------------

然后说我们在12月的付款为零,然后在明年1月又增加了200美元。

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------
-      112014  -    325.00 -           675.00 -
-----------------------------------------------
-      122014  -      0.00 -           675.00 -
-----------------------------------------------
-       12015  -    200.00 -           475.00 -
-----------------------------------------------

这是我奋斗的地方。我的理解是付款部分是正确的。它们均在每个记录中按月汇总。因此,如果需要年份,季度等,则可以进一步汇总。

但是储备金额不同。这是一个平衡。并且企业希望查看每个月的余额。但是您不能在此字段上进行汇总。如果这样做,您将获得一些奇怪的结果。

不知何故,这让我感到不对。但是我不能如实地说我已经足够建模或足够了解。我只能说的是我所知道的。据我所知,事实中的所有值都应具有相同的粒度。

这两个数字具有“月”的相同粒度,但是它们并不是从它们所代表的角度出发。一个是一个月内的总计美元。另一个只是平衡。

它是否正确?我一直在回推这种设计。我这样做有错吗?可以这样做吗?还是我对不良设计的“代码异味”感觉是准确的?

任何帮助,将不胜感激。注意:请不要只说“应该是X方式”,请解释为什么要这样,以便我可以从中学习。

编辑:恩,我了解到我对事实的最初理解是错误的。粒度不是每月一次。粒度是事务级别。因此,这意味着在MONTH_YEAR(即实际上是财务报告期)内,将有多个付款和回收交易。这些将按日期或交易日期发布。但是由于业务可以查看先前的报告,并且还因为数据是如何存储在旧系统中的,所以他们希望同时放置交易数据(每行一行)和每月储备金(每月一行) )。

得知这一点后,我意识到问题并不仅仅是谷物,而是添加剂,而非添加剂,甚至是半添加剂,这是我从一开始就怀疑的问题。我们的DBA小组与项目小组讨论了此事,并报告说他们正试图在同一事实中放入两种不同的谷物,这是不正确的。他们应该要么将交易发挥作用到每月的水平,然后让他们就可以拥有付款,回收和每月的准备金余额(即半累加事实),因为一切都会按月进行。或者他们需要找到一种将准备金余额分解为交易的方法,以保留交易级别的粮食。或者他们需要将事实分解为两个事实。一个可以是准备金余额的每月水平。另一个可以在付款和回收的交易级别。(他们也没有理由也不能将付款和回收额也放在每月级别的事实中。这仅取决于业务需求。)

根据我所学的知识,我将把托马斯的答案标记为正确的答案。但是,我觉得从原始问题开始的讨论仍然是其他人可以借鉴的好方法,因此,我会将问题的原始部分保留下来。我还打算悬赏尼卡丹的答案,因为它教会了我很多有关加性,非加性和半加性事实的知识,并且纠正 我对尺寸建模的许多误解。

Answers:


5

您的代码嗅觉直觉得到了很好的磨合。

您正在处理的reserves 是Kimball所说的“半加法事实”。它不能很好地累积到季度或年份。

典型的解决方案是有两个事实表,一个用于累加事实(payments在您的情况下),一个用于非累加事实。非累加的事实实际上并不需要在月份级别上添加谷物,您可以将它们一直存储到一天,事情仍然可以正常进行。

对非加性事实的reserve查询与其他事实不同。您需要做出一个业务决策:reserve在年度级别上意味着什么?是一年的最后一个月,还是一年中平均月份?无论您做出哪种选择,都可以在Kimball书中关于非可加事实的章节下找到对其进行建模的解决方案。

请注意,如果您使用诸如Analysis Services之类的多维数据集产品,即使将汇总全部存储在一个表中,也可能使聚合“正常工作”。但是,我更喜欢将它们分开,这样关系查询更容易编写(事实也更容易加载)。


因此,您建议将这两个值分解为两个事实,一个加法和一个非加法?(这实际上是我所追求的。)即使如此,您能提供一个理由吗?Kimball甚至说实际上不要混合加性值和非加性值吗?
克里斯·奥尔德里奇

4
或者,您可以将非加法事实reserve变成加法事实payment into reserve,其粒度级别与payment out of reserve现在相同。
mustaccio 2014年

@ChrisAldrich:考虑要在查询中合并一年的“付款总额”和同一年的“储备金”值的查询。如果将两个事实都合并到同一张表中,则会遇到一些讨厌的窗口查询。如果您在单独的表中具有这两个度量,则编写该查询很简单。
Thomas Kejser 2014年

7

您是正确的:“ 不得将不同的谷物混入同一事实表中 ”。

但是,月底的准备金余额与月底的付款总额相同。事实之一是半加性的。事实类型(是否添加)不能定义表格的纹理。

根据您的描述,我将您的粮食视为“每月索赔快照”,这使事实表成为“ 定期快照事实表 ”。

本文中, Kimball在同一事实表中有一个加法和半加法事实的示例。

这是数据仓库工具包(第116页)中具有半加法事实的定期快照的示例:

Kimball的数据仓库工具包,第116页

最佳实践是拥有一个交易事实表,该表将反映最低原子级别上的准备金的每个变化(支付和调整)。当您处理索赔时,通常原子级别不是索赔而是子索赔(您的保险公司可能有其自己的条款)。通常,每个子索赔将代表索赔的不同方,以及每个方的付款/准备金。例如,可能没有向被保险人付款,但是由公司受伤人员向未保险人付款,以及向医院和律师付款。

根据您的BI工具的性能,您可以直接使用交易事实表来获取每月的付款和余额。或者,您可以每天或在月末从交易中更新定期快照事实表。

处理半加性事实的能力将取决于您使用的BI层。有些工具可以轻松处理半加性事实,而有些则不能。

Kimball的主要书籍(The Data Warehouse Toolkit)具有关于保险的完整章节(16)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.