web-dev-qa-db-ja.com

データマート/倉庫でのタイムゾーンの処理

私たちはデータマート/倉庫のビルディングブロックを設計し始めており、すべてのタイムゾーンをサポートできる必要があります(私たちのクライアントは世界中から来ています)。オンライン(および本)でのディスカッションを読むと、一般的な解決策は、ファクトテーブルに日付と時刻のディメンションとタイムスタンプを個別に設定することです。

しかし、私が答えるのに苦労している質問は、動的なタイムゾーンの要件を考慮すると、日付と時刻のディメンションが実際にどのように役立つかです。時間ディメンションはもう少し理にかなっていますが、日付ディメンションで苦労しています。日付ディメンションの一般的な設計アプローチには、通常、曜日名、曜日、月名などのプロパティが含まれます。私が抱えている問題は、11:00 PM)です。 、2013年12月31日UTCは、UTC + 2以降のすべてのタイムゾーンで2014年1月1日水曜日です。

したがって、すべてのクエリ(およびレポート)でこれらすべてのタイムゾーン変換を行う必要がある場合、おそらく使用しない(これらのように思われる)これらのプロパティを保持して保存する意味は何ですか?一部の人々は、タイムゾーンごとにファクト行を持つことを提案しますが、それは私にはばかげているようです。毎月数百万のレコードを保存できる必要があります。

他の人は、タイムゾーンブリッジテーブルを持つことを提案しますが、これはある程度の意味がありますが、クライアントアプリとレポートが日付から簡単に理解できるはずのことを達成するための追加の複雑さと結合のようにも見えます(レポートは主にWebベースになります)日付の変換、表示、およびフォーマットを支援する無数のライブラリーがある場合)。

私が考えることができる唯一のことは、日付と時間でグループ化することの容易さとおそらくパフォーマンスですが、日付部分でグループ化することはどれほど悪いことですか(MS SQLを使用していますが、数百万の行をクエリすることになります)、または考慮する必要があります月曜日などのほとんどのリテラルはタイムゾーンが機能するときにあまり意味がないので、ほとんどの場合、時間、日、月、年の数以下の非常に単純な日付と時刻のディメンションですか?

12

まず...

分離Datime/TimeDateディメンションに入れ、Timeディメンションを入れるのは間違いありません。

複数のタイムゾーンを管理するには、DateKeyTimeKeyを複製して、次のようにする必要があります。

  • LocalDateKey
  • LocalTimeKey
  • UtcDateKey
  • UtcTimeKey

あなたは言う...

私が抱えているすべての問題は、2013年12月31日火曜日のUTCで11:00 PM)が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時間のローカライズを除く)読者の視点):

  • 計算をクエリに常駐させると、クエリに余分なパフォーマンス負荷がかかり、レポートに対してこのクエリを実行する必要がある回数が乗算されます(これは、数百万の行を読み取るときに問題になります)。
  • 各クエリで計算が正しく維持されるようにするための追加の負担(特に夏時間を考慮に入れる場合)
  • クエリがシークではなくインデックススキャンを実行するように列で計算を実行するため、列が含まれるインデックスの範囲スキャンを防止します(通常、各データページを読み取る必要があるため、よりコストがかかります);これはnon - sargableとして知られています。
    • コメントによる編集:これは、変換を実際のクエリにプッシュする場合に適用されます
  • 追加のUTCの日付と時刻を利用できるという概念を使用すると、この概念を採用して、これをStandardisedDateKeyまたはCorporateHQDateKeyと呼ぶことで拡張できます。UTC日付テーブルの代わりに他のビジネス合意標準に基づいて標準化する
  • 2つの別個の列タイプ(ローカルとUTC)があるため、地理的距離を横に並べて比較できます。考える->オーストラリアの誰かがローカルとUTCの両方でタイムスタンプが付けられたレコードを入力し、ニューヨークの誰かがローカル(オーストラリア)の日付と時刻ニューヨークでのUTC日付と時刻の表現。これにより、オーストラリアのカウンターパートが日中(オーストラリア時間)に何をしたかが、夜中(ニューヨーク時間)に発生したことがわかります。この時間の比較は、多国籍企業では不可欠です。
7
Adrian Torrie

この回答が簡潔であることをあらかじめお詫びし、私が勤務していないときは詳しく説明する予定です。

日付と時刻のテーブルを使用すると、データを簡単に集計できるという利点があります。多くの場合、それはその性質のものを月または営業日でソートする最も簡単な方法です。ただし、これは必ずしもタイムスタンプの有用性を置き換えるものではありません。特定のケースでは、UTCタイムスタンプ。タイムスタンプを取得したら、レポートまたはプレゼンテーションレイヤーでタイムスタンプを現地時間に変更するだけです。範囲スキャンを回避するために、リクエスト範囲もUTC時間に変換していることを確認してください。

他の質問やコメントがある場合は、遠慮なく尋ねてください。

0
Zane