首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在星型模式中,当维度具有日期属性时,我应该做什么?

在星型模式中,当维度具有日期属性时,我应该做什么?
EN

Database Administration用户
提问于 2012-11-16 06:14:38
回答 2查看 10.8K关注 0票数 4

我正在尝试学习有关维度模型和星型模式的知识。假设我有一个销售事实表,记录零售商店的总销售额,例如,四个维度、日期、客户、商店和促销(如优惠券)。(下面是伪模式)。

我非常喜欢用诸如一周中的一天这样的属性预先填充日期维的想法,这样你就可以很容易地通过看似复杂的条件来过滤事实,比如“过去10年中的第二季度星期六”。

现在,假设我希望升级维度有Start_Date和End_Date属性,这两个属性表示促销的开始和结束。我该怎么做?我考虑过这个问题,想出了三个不太理想的解决方案:

1)使Start_Date和End_Date具有规则的原子属性( ISO8601字符串或DB的datetime对象),并且只允许有限制的过滤。

2)为Date表设置Start_Date和End_Date外键,打破星型模式,但允许使用与完整日期维度相同的过滤功能。

3)包含Start_Date_Day_of_Week、Start_Date_Quarter等属性,维护星型模式,但增加维度大小,并在Promotions维度中基本上复制Date维度的结构。

代码语言:javascript
复制
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...
EN

回答 2

Database Administration用户

发布于 2017-03-03 22:13:28

老问题&我知道原来的海报是不活跃的,但由于它出现在谷歌搜索,我想我应该补充我的想法。

1)使Start_Date和End_Date具有规则的原子属性( ISO8601字符串或DB的datetime对象),并且只允许有限制的过滤。

如果主要目标是信息性的(例如,人们希望在报告中包含促销的开始/结束日期),将日期属性放入现有维度是有意义的。但是,如果目的是进行筛选,那么对原子日期属性的筛选将是相对痛苦的。

2)为Date表设置Start_Date和End_Date外键,打破星型模式,但允许使用与完整日期维度相同的过滤功能。

这种类型的雪花被称为OU触发器维度,可以在星型模式中接受。(http://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/outrigger-dimension/)。我想你就是这么做的。

3)包含Start_Date_Day_of_Week、Start_Date_Quarter等属性,维护星型模式,但增加维度大小,并在Promotions维度中基本上复制Date维度的结构。

复制将变得混乱(维护多个日期字段,特别是因为您在同一维度中有多个日期)。这也使得未来的维护更加复杂:如果你想改变你的日期维度,你必须重复在几十个地方(或有一个不一致的用户体验)的改变。

另一方面,这可能是一个有效的选择,例如,只有一两种方式,你知道人们想要过滤晋升。例如,如果您知道最终用户希望快速筛选到活动促销或“在过去30天内关闭的促销”,则可以计算并添加该属性作为促销维度中的特定属性,而不是链接到促销开始和结束日期的完整日期维度。(虽然从一个或两个属性开始的东西可以迅速扩展,因为最终用户发现他们想要过滤的时间周期越来越多。)

有第4和第5种选择,具体取决于您打算通过促销开始/结束日期筛选的内容:

(

4)在Sales表中添加促销开始/结束日期字段作为键。

每次使用促销时,您都会存储相同的信息,因此乍一看,感觉像是大量的重复。但去正规化是星型模式中游戏的名称。如果您的目标是根据促销开始日期或结束日期(即促销开始日期为上个月的销售日期)筛选到销售,则我建议在OO触发器维度上这样做。

5)创建一个新的、没有事实根据的事实表,用于晋升

如果您的目标根本不是过滤销售,那么一个没有事实根据的事实表可能是一个更好的解决方案。例如,这可以告诉您在给定日期(无论是否有关联的销售)有多少促销活动。更多信息:http://www.kimballgroup.com/2011/04/design-tip-133-factless-fact-tables-for-simplification/

我在维度建模方面的经验是,最好的解决方案通常取决于最终用户试图实现的目标。如果你(或他们)还不确定他们想要达到什么目的(也就是说,你知道升职有开始和结束日期,仅此而已),我会从选项1开始。这会把信息放在你的模型中,而不需要做太多的工作。

如果后来发现终端用户试图按开始和结束日期过滤销售,我会考虑第2或#4。如果最终用户试图独立于销售分析促销,我会看第5。

票数 2
EN

Database Administration用户

发布于 2012-11-16 13:18:50

我建议使用选项2。Date是星型模式世界中的一个特例:加入这个维度所带来的好处远远超过你想要做的雪花。

选项1意味着您将失去拥有数据仓库的许多分析好处:例如,您不能轻松地寻找客户在模式上可能会根据年龄而有所不同。

选项3将涉及维度表中的巨大爆炸:您将无缘无故地携带大量额外的属性。通常情况下,这并不坏--星型模式的全部目的是去修饰和简化你的维度结构--但这是一个罕见的情况,在这种情况下,你会频繁地对很多属性这样做,每次你更新维度中的一行时,你可能也必须更新所有这些属性。这是对增量维度负载的负面性能影响,而不是真正使业务用户更容易理解该模型。这甚至可能会让事情变得更糟:如果你拥有与70+日期相关的属性(比如标准年份、不同类型的财政年度等),他们的眼睛可能会变得呆滞。对于维度上的每个日期。在140或更多与日期相关的列中找到实际的维度属性会变得更加困难。

为了帮助您在夜间睡觉,您还可以创建两个图形模型:一个是真实的数据模型,另一个是“无数据”的数据模型。“无数据”模型将剥离其他维度和日期之间的连接,并且看起来更像一个天然的星型模式。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/28775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档