2

我希望有人能指出一些关于何时计算存储在数据仓库中的计算值的最佳实践。

考虑以下示例,

CREATE TABLE
(
    MyFactID INT NOT NULL IDENTITY(1, 1),
    OrderDimID INT NOT NULL, -- FK To OrderDimension
    StartDate DATETIME NOT NULL,
    CompletedDate DATETIME NULL,
    ElapsedCalendarTimeInMinutes INT NULL,
    ElapsedBusinessTimeInMinutes INT NULL
)

在此示例中,已用日历时间(以分钟为单位)是从开始日期到结束日期的时间(以分钟为单位)。然后,我们的工作时间反映了这些日历日内可用的工作时间。

目前,我们正在 ETL 期间计算此值并插入两个日期。我想知道这是否是执行此操作的正确位置。

其他一些想法是:

A) 通过仅在事实表中存储开始和结束日期来使用索引视图,然后创建一个以分钟为单位计算经过时间的视图,并具有一个使用函数来计算工作日的计算列。

B) 使用 After 触发器在插入发生后更新经过的日历时间和业务时间,该插入将完成日期插入或更新为非空值。

我觉得这应该在数据库中完成,这样如果对结束日期或业务时间的计算进行任何更改,它就会反映出来。在 ETL 期间这样做似乎很容易出现问题。

对此的任何想法表示赞赏!

更新:至少有 6 列以这种方式确定。我们有营业时间、营业时间和日期(营业时间为 12 小时);然后我们有客户分钟、小时和天数(通过查找表确定客户的工作时间);那么我们只有日历分钟、小时和天(尽管这些没有被存储;只有分钟)。由于这是一个 DW,我希望所有数据都存在并且不需要计算。对我来说,确保 ETL 正确并应用到任何地方似乎比在基础数据之上创建视图以获取计算信息要多做一些工作。

4

2 回答 2

3

最简单的方法应该是最好的解决方案:

在您的 ETL 过程中(让我们假设这是SSIS,但您可以外推到其他技术):

  1. 创建数据流以将表从操作数据库复制到后台数据仓库。
  2. 使用T-Sql 任务更新事实表。一个合并语句就足够了:

合并样本:

MERGE Target AS T
USING Source AS S
ON ( __  matching criteria ___) 
WHEN NOT MATCHED BY TARGET
    THEN INSERT( OrderDimID, startDate, ... ) VALUES( ... )
WHEN MATCHED 
    THEN UPDATE SET T.ElapsedCalendarTimeInMinutes = ___some calculations___
WHEN NOT MATCHED BY SOURCE
    THEN DELETE (?)

这避免了触发器和索引视图。

于 2012-08-23T19:25:15.027 回答
0

您可以使用计算列, http: //msdn.microsoft.com/en-us/library/ms191250 (v=sql.100).aspx 。有两种口味,非持久化和持久化。当您查询数据时,非持久化运行计算。Persisted 存储插入时的值,然后根据对基础公式数据的更改进行更新。对于数据仓库应用程序,我会推荐持久化。

于 2012-08-29T19:36:03.370 回答