首先...
分离Datime/Time
到一个Date
维度和Time
层面肯定是要走的路。
要管理多个时区,您需要复制DateKey
和,TimeKey
以便您具有以下内容:
LocalDateKey
LocalTimeKey
UtcDateKey
UtcTimeKey
你说...
我所遇到的问题是,在UTC + 2之后的所有时区中,UTC的2013年12月31日(星期二)晚上11:00是2014年1月1日(星期三)。
通过在上方列出我列出的4列,可以使用表别名将事实表连接到“日期和/或时间”维度(在Kimball术语中,这些别名维度表被称为“角色扮演维度”),因此您将具有以下内容:
/*
Assumes the following:
- [DateLongName] has the format of this example "Tuesday, December 31, 2013"
- [TimeShortName] has the format of this example "11:00 PM"
- Both [DateLongName] & [TimeShortName] are strings
*/
select
-- Returns a string matching this example "11:00 PM Tuesday, December 31, 2013"
localTime.TimeShortName + ' ' + localDate.DateLongName
,utcTime.TimeShortName + ' ' + utcDate.DateLongName
,f.*
from
FactTableName AS f
-- Local Date and Local Time joins
inner join dbo.Date AS localDate
on localDate.DateKey = f.LocalDateKey
inner join dbo.Time AS localTime
on localTime.TimeKey = f.LocalTimeKey
-- Utc Date and Utc Time joins
inner join dbo.Date AS utcDate
on utcDate.DateKey = f.UtcDateKey
inner join dbo.Time AS utcTime
on utcTime.TimeKey = f.UtcTimeKey
最后...
当你正在构建一个数据集市,而不是OLTP数据库,本地和UTC时间的产生应该在你的ETL进行,不要在有以下原因的任何客户端应用程序(除了的UTC时间本地化报告读者的观点):
- 将计算驻留在任何查询中会给它们带来额外的性能负担,乘以您必须对所拥有的任何报告运行所述查询的次数(在读取数百万行时非常重要)
- 确保在每个查询中正确维护计算的额外负担(尤其是考虑到夏时制时)
- 防止对该列所属的任何索引进行范围扫描,因为您将对该列执行计算,从而迫使查询执行索引扫描而不是搜索(由于需要读取每个数据页,因此通常更昂贵);这被称为是非可优化搜索。
- 根据评论进行修改:如果您将转换向下推到实际查询中,则适用此规则。
- 使用具有其他可用UTC日期和时间的概念,没有什么可以阻止您采用此概念并通过调用this
StandardisedDateKey
或扩展它CorporateHQDateKey
,在此您可以基于其他业务约定标准对UTC日期表进行标准化
- 具有两种单独的列类型(本地和UTC),可以跨地理距离进行并排比较。思考->澳大利亚某人输入了带有本地和UTC时间戳的记录,纽约某人读取了带有本地(澳大利亚)日期和时间以及纽约UTC日期和时间表示的报告,从而发现了一些东西他们的澳大利亚同行是在白天(澳大利亚时间)的中午发生的(纽约时间)。在跨国公司中,这种时间比较是必不可少的。