use*_*481 5 data-warehouse dimension
我正在尝试了解维度模型和星型模式。假设我有一个销售事实表,记录零售商店的总销售额,其中有四个维度:日期、客户、商店和促销(如优惠券等促销活动)。(下面的伪模式)。
我真的很喜欢用星期几等属性预先填充“日期”维度的想法,这样您就可以通过看似复杂的条件(例如“过去 10 年第二季度的星期六”)轻松过滤事实。
现在,假设我希望促销维度具有 Start_Date 和 End_Date 属性,它们表示促销的开始和结束。我该怎么做呢?我想了想,得出了三个不太理想的解决方案:
1) 使 Start_Date 和 End_Date 成为常规的原子属性(ISO8601 字符串或数据库的日期时间对象),并且仅允许有限的过滤。
2) 将 Start_Date 和 End_Date 外键设置为 Date 表,打破星型模式,但允许与完整 Date 维度相同的过滤功能。
3) 包括 Start_Date_Day_of_Week、Start_Date_Quarter 等属性,维护星型模式,但增加维度大小,并在促销维度中复制日期维度的结构。
Sales Table
-----------
Date key (FK to Dates table)
Promotion key (FK to Promotions)
Customer key (FK to Customers table)
Store key (FK to Stores)
Sales Amount
Date Table
----------
Date Key (PK)
Month
Day of week
Day of month
Day of Quarter
Day of year
Holiday?
Quarter
Day since Epoch
Month since Epoch
etc...
Promotion Table
---------------
Promotion Key (PK)
Type (Coupon code, 2-for-1 sale, 50% off, etc)
Start_Date
End_Date
Customer Table
--------------
Customer Key (PK)
Name
Age
Sex
etc...
Stores Table
------------
Store Key (PK)
Address
City State
Zip
etc...
Run Code Online (Sandbox Code Playgroud)
我建议选择#2。日期是星型架构世界中的一个特例:加入该维度所带来的好处远远超过了您想要加入的雪花。
选项#1 意味着您将失去拥有数据仓库所带来的许多分析优势:例如,您无法轻松地执行诸如查找客户因年龄而导致的模式差异之类的事情。
选项 #3 将涉及维度表中的巨大爆炸:您将无缘无故地携带大量额外属性。通常这还不错——星型模式的全部意义在于非规范化和简化维度结构——但这只是一种罕见的情况,在这种情况下,您会经常对如此多的属性执行此操作,并且每次更新维度中的行时,您可能还必须更新所有这些属性。这会对增量维度负载产生负面性能影响,而不会真正使业务用户更容易理解模型。这甚至可能使事情变得更糟:如果维度上的每个日期都有 70 多个与日期相关的属性(例如标准年、不同类型的会计年度等),他们的目光可能会变得呆滞。在 140 个或更多与日期相关的列中找到实际的维度属性会变得更加困难。
为了帮助您晚上睡觉,您还可以创建两种图形模型:一种是真实数据模型,另一种是“无日期”数据模型。“无数据”模型将剥离其他维度和日期之间的联系,并且看起来更像是自然的星型模式。