Sql-Server-2012

處理數據集市/倉庫中的時區

  • January 31, 2019

我們開始設計數據集市/倉庫的建構塊,我們需要能夠支持所有時區(我們的客戶來自世界各地)。從線上(和書籍)閱讀討論來看,一個常見的解決方案似乎是在事實表中具有單獨的日期和時間維度以及時間戳。

但是,我很難回答的問題是,考慮到我的動態時區要求,日期和時間維度實際上對我有什麼好處?時間維度更有意義,但我很難處理日期維度。日期維度的一般設計方法通常包括日期名稱、星期幾、月份名稱等屬性。我遇到的問題是 UTC 時間 2013 年 12 月 31 日星期二晚上 11:00 是星期三, 2014 年 1 月 1 日,在 UTC+2 之後的所有時區。

因此,如果我必須對每個查詢(和報告)進行所有這些時區轉換,那麼擁有和儲存這些我可能永遠不會使用的屬性有什麼意義(似乎)?有些人建議為每個時區設置事實行,但這對我來說似乎很荒謬。我們需要能夠每月儲存數百萬條記錄。

其他人建議有一個時區橋接表,雖然有一定的意義,但它似乎也需要額外的複雜性和額外的連接來完成我的客戶端應用程序和報告應該能夠從某個日期輕鬆計算出來的事情(報告將主要基於 Web那裡有無數的庫可以幫助轉換、顯示和格式化日期)。

我唯一能想到的是按日期和小時分組的簡便性和可能的​​性能,但是按日期部分分組的做法有多糟糕(我們正在使用 MS SQL,但我們將查詢數百萬行)或者我們應該考慮只是非常簡單的日期和時間維度,大多數情況下不超過小時、日、月和年的數字,因為大多數文字(例如星期一)在時區發揮作用時意義不大?

第一…

分成Datime/Time一個Date維度和一個Time維度絕對是要走的路。

要管理多個時區,您需要複製DateKeyTimeKey以便擁有以下內容:

  • 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 數據庫時,應在 ETL 中生成 Local 和 Utc 時間,而不是在任何客戶端應用程序中執行,原因如下(除了將 UTC 時間本地化到報告讀者的觀點):

  • 將計算駐留在任何查詢中會給它們帶來額外的性能負擔,乘以您必須為您擁有的任何報告執行所述查詢的次數(這在讀取數百萬行時很重要)
  • 確保在每個查詢中正確維護計算的額外負擔(尤其是在考慮夏令時時)
  • 防止對該列所屬的任何索引進行範圍掃描,因為您將對列執行計算,該計算會強制查詢執行索引掃描而不是查找(由於需要讀取每個數據頁,這通常更昂貴);這被稱為不可分割
    • **因評論而編輯:**如果您將轉換下推到實際查詢中,這適用。
  • StandardisedDateKey使用提供額外 UTC 日期和時間的概念,沒有什麼能阻止您採用此概念並通過呼叫 this來擴展CorporateHQDateKey
  • 擁有兩種單獨的列類型(Local 和 UTC),允許跨地理距離進行並排比較。想想 -> 澳大利亞的某個人輸入了一條帶有本地和 UTC 時間戳的記錄,紐約的某個人閱讀了帶有本地(澳大利亞)日期和時間以及UTC 日期和時間的紐約表示的報告,從而看到了一些東西他們的澳大利亞同行在中午(澳大利亞時間)發生在他們的時間(紐約時間)的半夜。這種時間比較在跨國企業中是必不可少的。

引用自:https://dba.stackexchange.com/questions/51752