我希望有人能指出一些关于何时计算存储在数据仓库中的计算值的最佳实践。
考虑以下示例,
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正确并适用于所有地方似乎更有效,而不是创建一个超出基础数据的视图来获取计算信息。
答案 0 :(得分:3)
最简单的方法应该是最佳解决方案:
在你的ETL过程中(让我们假设SSIS,但你可以推断其他技术):
合并样本:
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 (?)
这可以避免触发和索引视图。
答案 1 :(得分:0)
您可以使用计算列http://msdn.microsoft.com/en-us/library/ms191250(v=sql.100).aspx。有两种口味,非持久性和持久性。非持久性在查询数据时运行计算。持久化将值存储在插入上,然后根据对基础公式数据的更改进行更新。对于数据仓库应用程序,我建议保留。