我已经看到DateTime
拒绝使用合并尺寸的仓库的想法,但是我还没有看到真正清楚的原因。稍微简化一下,这是我现在正在构建的事实表:
Transactions
(
...
CreatedDateTimeSK INT NOT NULL, -- Four bytes per date...
AuthorizedDateTimeSK INT NOT NULL,
BatchSubmittedDateTimeSK INT NOT NULL,
BatchApprovedDateTimeSK INT NOT NULL,
SettlementDateTimeSK INT NOT NULL,
LocalTimeZoneSK TINYINT NOT NULL -- ...plus one byte for the time zone
)
这些DateTime
字段连接到DateTime表:
DateTimes
(
DateTimeSK INT NOT NULL PRIMARY KEY,
SQLDate DATE NOT NULL,
SQLDateTime DATETIME2(0) NOT NULL,
Year SMALLINT NOT NULL,
Month TINYINT NOT NULL,
Day TINYINT NOT NULL,
Hour TINYINT NOT NULL,
Minute TINYINT NOT NULL CHECK (Minute IN (0, 30)),
...
)
这是半小时的分辨率,因此每天有48条记录,在20年中为350,400条-相当可管理。
事件日期/时间在存储时会转换为UTC,但是通过LocalTimeZoneSK
字段和桥表,我们可以轻松地加入以获取本地时间:
TimeZoneBridge
(
DateTimeSK INT NOT NULL,
TimeZoneSK TINYINT NOT NULL,
PRIMARY KEY (DateTimeSK, TimeZoneSK),
LocalDateTimeSK INT NOT NULL
)
要获取今天创建的交易,UTC时间:
SELECT COUNT(*)
FROM Transactions AS T
INNER JOIN DateTimes AS CD ON T.CreatedDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'
要获取今天创建的交易,请在当地时间进行交易:
SELECT COUNT(*)
FROM Transactions AS T
INNER JOIN TimeZoneBridge AS TZB ON T.CreatedDateTimeSK = TZB.DateTimeSK AND T.TimeZoneSK = TZB.TimeZoneSK
INNER JOIN DateTimes AS CD ON TZB.LocalDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'
您可以通过更换被诱惑把事情简单化TimeZoneSK
了REAL
偏移(例如,-5.0美国中部夏令时间),但这将打破,如果是事实记录一些日期/时间是夏令时,有些则不是。
如果事实记录的事件可以发生在不同的时区,例如货运或航班,则每个日期都需要一个时区字段,并且每个日期最多五个字节。