まず...
次元と次元に分離Datime/Time
することは間違いなく進むべき道です。Date
Time
複数のタイムゾーンを管理するには、DateKey
およびを複製しTimeKey
て、次のようにする必要があります。
LocalDateKey
LocalTimeKey
UtcDateKey
UtcTimeKey
あなたは言う...
私が抱えている問題は、2013年12月31日火曜日の午後11時(UTC)が、UTC + 2以降のすべてのタイムゾーンで2014年1月1日水曜日であることです。
上記の4つの列を使用すると、テーブルエイリアスを使用して、ファクトテーブルを日付および/または時間ディメンションに結合できます(キンボール用語では、これらのエイリアスディメンションテーブルは「ロールプレイングディメンション」と呼ばれます)。次のようなものになります:
/*
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の日付と時刻を持つという概念を用いて
StandardisedDateKey
、またはCorporateHQDateKey
、代わりにUTC日付テーブルのあなたは、いくつかの他に基づいて標準化どこ事業合意標準を
- 2つの別個の列タイプ(ローカルとUTC)があるため、地理的な距離を横に並べて比較できます。考える->オーストラリアの誰かがローカルとUTCの両方でタイムスタンプが付けられたレコードを入力すると、ニューヨークの誰かがローカル(オーストラリア)の日付と時刻、およびニューヨークのUTC日付と時刻を含むレポートを読み取り、それによって何かが表示されます。彼らのオーストラリアの対応は、真昼中に(オーストラリア時間)真夜中に彼らの時間(ニューヨーク時間)に起こりました。この時間の比較は、多国籍企業では不可欠です。