1

我正在重新构建一个报告/数据仓库类型的数据库。我们目前有一个包含酒店粒度数据的表(即 HotelID 加上许多度量,包括 Last7DaysGross、Last28DaysXXX 等度量)。

我认为最好转移到位于 Hotel/StayDate 粒度的事实表。但是,对 HotelID 进行分组并包括 Last7DaysGross 等与日期相关的度量需要表现得非常好。

什么样的结构可以在这里工作?我认为我不能像我希望的那样使用索引视图,因为它们有多重限制(没有子查询等)。为了获得合理的性能,我需要在酒店级别(从 HotelStayDate 级别聚合?)这是人们最常查询的级别。我是否需要实际创建诸如 Last7DaysGross 之类的字段?这似乎不是一个好的设计,但我很难想出另一个。

抱歉这个问题有点含糊。还有什么我在这里想念的吗?我知道这些与日期相关的措施通常会在前端级别(即在诸如 Business Objects 之类的工具中)完成。但是,对于这个项目,我们需要将它保存在数据库中。

谢谢,西尔维亚

编辑:

感谢所有深思熟虑的评论!我接受了 David Marwick 的回答,因为他有扩展日期维度的想法。我什至没有想到这个想法,听起来很值得一试。

稍微扩展一下 David Marwick 的想法,我想出了这个想法。我可能会尝试看看它实际上是如何工作的:

DateDimension
   DateKey
   DateKeyBeginLast28Days
   DateKeyEndLast28Days

Fact
   DateKey
   GrossTransactions

然后查询时:

Select
   DateKey
   ,SumLast28Day = sum(GrossTransaction)
from Fact
   join DateDimension
      on Fact.DateKey >= DateDimension.DateKeyBeginLast28Days
      and Fact.DateKey <= DateDimension.DateKeyEndLast28Days
group by DateKey
4

4 回答 4

1

聚合事实表在数据仓库中是完全可以接受的。

如果你还没有准备好,我会推荐下面的书

数据仓库工具包

在这里,Kimball 指出将事实表预聚合到聚合事实表中很好,但是它确实声明它们应该类似于汇总级别的“基本”事实表。

我怀疑报告字段的引入应该在您的前端报告工具或多维数据集查看器中。

于 2012-05-02T12:55:23.500 回答
1

正如 David 所说,预先聚合一些总数(在 ETL 过程中)以使重要的查询运行得更快并没有任何问题。即使在操作数据库中,这也是一种常见的技术,如果您知道某些聚合经常使用,那么它在数据仓库中很有意义。

因此,您当然可以创建一个名为FactHotelRevenueSummary(或任何与您现有的命名约定相匹配)的表,其中包含任意数量的HotelID, Last7DaysGross, Last28DaysGross其他聚合。

我认为首先要考虑的要点是:

  • 由于可观察到的性能问题,预聚合确实是必要的,即您正在增加数据库的复杂性以解决实际问题,而不是因为您模糊地感觉它可能会有所帮助
  • 您的 ETL 流程会检查以确保聚合数据与“原始”数据完全匹配,否则您将获得不同的数字,具体取决于您查询的事实表,这会对用户信心产生非常负面的影响
于 2012-05-02T14:30:05.770 回答
1

我认为您在 [Hotel, Date] 谷物中放置一张桌子然后卷入酒店的设计听起来不错。正如 Damir 指出的那样,它使您的读取查询变得简单,并且可以轻松地添加/删除未来的聚合度量(请记住,围绕您将来可能拥有的需求进行设计通常是一个坏主意)。

Pondlife 也有好处。您的定性要求可能决定维护聚合表的可行性,例如系统需要多久更新一次(每天、每小时、15 分钟、实时?),测量需要多准确(也许用户只需要粗略了解每家酒店的表现)、读取源交易数据的成本、源交易数据的长期可用性(是否被存档)等。

如果您选择添加 [Hotel, StayDate] 粒度事实表而不维护聚合,那么也许您可以在维度中探索一些技巧以节省时间。也许像包含 [date, date_in_last_7_days] 的 7 天日期维度(因此每个日期有 7 条记录),以防直接连接与查询过去 7 天的范围可以为您节省任何时间。这可能是一个愚蠢的例子,但类似的东西。日期尺寸很小。

最后,如果您需要提高性能,请考虑硬件优化,例如将表移动到内存中(尤其是维度或非大型事实表)。

于 2012-05-03T21:15:07.113 回答
0

取决于,通常的查询(过去 7 天)看起来像

select
    HotelName
  , sum(SaleAmount) as Sales
from factSale as s
join dimDate  as d on d.DateKey  = s.DateKey
join dimHotel as h on h.HotelKey = s.HotelKey 
where DaysAgo between 1 and 7
group by HotelName 
;

但是,假设您有一份报告,其中包括运行总和(跨期间)及其变化。报告布局可能如下所示:

| Date | 1-Day | Change-1-Day % | 7-Day | Change-7-Day % | 28-Day | Change-28-Day | 90-Day | Change-90-day % |

不再那么简单了。因此,使用标准期间的预先计算字段创建聚合(事实)表并在该表上运行查询要容易得多。

所以聚合(事实)表可能看起来像

factRunningSum
----------------------------
DateKey     integer  (PK)
HotelKey    integer  (PK)
Sale_1_Day  decimal(19,2)
Sale_7_Day  decimal(19,2)
Sale_28_Day decimal(19,2)
Sale_90_Day decimal(19,2)
于 2012-05-03T17:08:33.260 回答