新しいデータウェアハウスの設計を開始したばかりで、日付と時刻のディメンションがどのように機能するかを設計しようとしています。複数のタイムゾーン(おそらく、少なくともGMT、IST、PST、EST)をサポートできる必要があります。最初は、1つの広い結合された日時ディメンションを15分程度まで細かくすることを考えていました。これにより、ファクトテーブルに1つのキーがあり、サポートされているすべてのタイムゾーンのすべての異なる日時データが1つのディメンションテーブルにあります。 (つまり、日付キー、GMT日付、GMT時間、IST日付、IST時間など...)
キンボールは、テーブルが大きくなりすぎないように(データウェアハウスツールキットp。240)、時間ディメンションとは別の日ディメンションを使用することを推奨していますが、これは、各タイムゾーンのファクトテーブルに2つのキーがあることを意味します。サポートする必要があります(1つは日付用、もう1つは時刻用)。
私はこの領域で非常に経験が浅いので、誰かが2つのアプローチ間のトレードオフ、つまりパフォーマンスとすべての異なるタイムゾーンキーの管理のトレードオフを知っていることを望んでいます。多分他のアプローチもあるかもしれませんが、ファクトテーブルにタイムゾーンごとに別の行があることを話している人を見たことがありますが、ファクトテーブルが数百万の行である場合、タイムゾーンを追加するために4倍にする必要があるという問題のようです。
15分の粒度を使用すると、日付時刻ディメンションテーブルに1年あたり131,400(24 * 15 * 365)行が含まれます。これは、パフォーマンスにとってそれほどひどく聞こえませんが、いくつかをテストするまではわかりません。プロトタイプクエリ。ファクトテーブルに個別のタイムゾーンキーがあることの他の問題は、クエリが目的のタイムゾーンに基づいてディメンションテーブルを別の列に結合する必要があることです。これはおそらくSSASが処理するものですが、よくわかりません。
どんな考えにも感謝します、-Matt
日付と時刻を別々にすると、時間による集計を非常に簡単に行うことができます。たとえば、クエリを実行して、1日の中で最も忙しい時間帯を見つけたい場合などです。これは、別の時間ディメンションを使用して非常に簡単に実行できます。
また、タイムキーは1つだけにする必要があります。 GMT/EST時間のどちらかを決定します。次に、これをファクトテーブルで使用します。他のタイムゾーンに基づいてレポートを実行する必要がある場合は、アプリケーションまたはクエリで変換するだけです。
DataWarehouseを実装して複数のタイムゾーンをサポートし、できるだけ効率的にすることを決定した方法のフォローアップです。「タイムゾーン」だけでなく、タイムゾーン(ID、名前など)のテーブルを作成することにしました。次のような「ブリッジ」テーブル:
time_zone_bridge
---------------
date_key_utc
time_key_utc
timezone_id
date_key_local
time_key_local
このようにして、通常の日付と時刻のディメンションテーブルを小さく保ち、すべてのファクトをUTCの日付/時刻キーにリンクし、別のタイムゾーンでレポート/グループ化する必要がある場合は、タイムゾーンブリッジテーブルを介して結合する必要があります。ローカルの日付/時刻キーを日付と時刻のディメンションテーブルにリンクします。これはSSISから呼び出されたC#コードを使用してタイムゾーンブリッジテーブルを作成します。これは、SqlServerから直接TZを行うよりもはるかに複雑ではないためです。
統合された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)),
...
)
これは30分単位の解像度なので、1日あたり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)に置き換えることで、物事を簡素化したくなるかもしれませんが、これは、ファクトの日付/時刻があると故障します。レコードは夏時間にあり、一部はそうではありません。
ファクトレコードのイベントが、出荷やフライトなどの異なるタイムゾーンで発生する可能性がある場合は、日付ごとにタイムゾーンフィールドが必要であり、日付あたり最大5バイトです。