Gestione dei fusi orari nel data mart / magazzino


12

Stiamo iniziando a progettare gli elementi costitutivi di un data mart / magazzino e dobbiamo essere in grado di supportare tutti i fusi orari (i nostri clienti provengono da tutto il mondo). Dalla lettura delle discussioni online (e nei libri), una soluzione comune sembra essere quella di avere una dimensione data e ora separata, nonché un timestamp nelle tabelle dei fatti.

Tuttavia, la domanda a cui ho difficoltà a rispondere è: a cosa servono effettivamente le dimensioni di data e ora, considerando i miei requisiti di fuso orario dinamico? Una dimensione temporale ha un po 'più senso, ma sto avendo difficoltà con la dimensione data. Un approccio di progettazione generale per una dimensione data di solito include proprietà come il nome del giorno, il giorno della settimana, il nome del mese, ecc. , 1 gennaio 2014 in tutti i fusi orari successivi a UTC + 2.

Quindi, se dovrò fare tutte queste conversioni di fuso orario su ogni singola query (e report), qual è il punto di avere e archiviare queste proprietà che probabilmente non userò mai (sembra)? Alcune persone suggeriscono di avere file di fatti per ogni fuso orario, ma mi sembra ridicolo. Dobbiamo essere in grado di archiviare milioni di record ogni mese.

Altri suggeriscono di avere una tabella di bridge di fuso orario che, sebbene abbia un senso, sembra anche più complessità e unioni extra per realizzare qualcosa che le mie app e i miei report client dovrebbero essere facilmente in grado di capire da una data (il reporting sarà principalmente basato sul web dove ci sono una miriade di librerie per aiutare a convertire, visualizzare e formattare le date).

L'unica cosa che mi viene in mente è la facilità e possibilmente le prestazioni del raggruppamento per data e ora, ma quanto è brutta una pratica raggruppare per datapart (stiamo usando MS SQL ma interrogheremo milioni di righe) o dovremmo considerare solo dimensioni della data e dell'ora estremamente semplici con non più di ore, giorno, mese e anno per la maggior parte dato che la maggior parte dei letterali come il lunedì non significherebbe molto quando entrano in gioco i fusi orari?


1
Penso che ciò che cerchi sia il tipo di dati datetimeoffset e quindi memorizzare tutte le date nella loro rappresentazione UTC. Quindi, quando è necessario estrarre i dati, si interrogano i dati nel loro valore UTC e si lascia che il client li rappresenti nella sua ora locale.
Allan S. Hansen,

6
Non riesco a pensare a nessun motivo per cui vorrei memorizzare la data indipendentemente dall'ora. Archivia tutto come datetime UTC e lascia che il livello di presentazione si preoccupi della localizzazione.
billinkc,

1
Sono d'accordo con @billinkc. Non sono sicuro di quali vantaggi trarrai dalla memorizzazione di data e ora separatamente quando finiresti costantemente per rimetterli insieme per fare la conversione del fuso orario.
mmarie,

2
@billinkc: "Non riesco a pensare a nessun motivo per cui vorrei memorizzare la data indipendentemente dall'ora". - Io posso. Ogni volta che stai costruendo un cubo fuori dal magazzino. Avere dimensioni di data e ora del giorno separate è un luogo comune e la migliore pratica.
Mitch Wheat,

@MitchWheat Potresti aiutarmi a capirlo (forse stai componendo una risposta)? Sono una società adulta con vendite globali e alle 2300 GMT ho un forte aumento delle vendite. Trascino la mia affettatrice nel rapporto e sicuramente, nei fusi orari orientali e centrali degli Stati Uniti, potrei avere delle vendite in corso mentre le persone raccolgono alcune bevande confezionate sulla strada di casa, ma sono le 0330 in India, nessuno raccoglie Kingfisher a quell'ora e le 6 del mattino di Perth sono potenti ma chi si lava i denti con VB? Invece, le persone acquistano alcol dopo il lavoro in modo così 1700 ma ho quindi bisogno di preoccuparmi dei limiti di data
billinkc

Risposte:


7

In primo luogo ...

Separare Datime/Timein una Datedimensione e una Timedimensione è sicuramente la strada da percorrere.

Per gestire più fusi orari è necessario duplicare DateKeye TimeKeycosì da disporre di quanto segue:

  • LocalDateKey
  • LocalTimeKey
  • UtcDateKey
  • UtcTimeKey

Tu dici...

Il problema che sto riscontrando è che alle 23:00 di martedì 31 dicembre 2013 in UTC è mercoledì 1 gennaio 2014 in tutti i fusi orari successivi a UTC + 2.

Avendo le 4 colonne che ho elencato sopra di te, sarai in grado di unire la tabella dei fatti alla dimensione Data e / o Tempo usando gli alias di tabella (nella terminologia di Kimball queste tabelle di dimensioni con alias sono note come "Dimensioni di gioco di ruolo"), quindi avresti qualcosa di simile al seguente:

/*
    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 

In chiusura...

Durante la creazione di un data mart e non di un database OLTP, la generazione degli orari Local e Utc deve essere eseguita nell'ETL , NON in qualsiasi applicazione lato client per i seguenti motivi (a parte la localizzazione dell'ora UTC sul rapporto prospettiva del lettore):

  • Il fatto che il calcolo risieda in qualsiasi query comporta un ulteriore onere per le prestazioni, moltiplicato per il numero di volte in cui è necessario eseguire detta query per tutti i report in uso (questo è importante quando si leggono milioni di righe)
  • Onere aggiuntivo di garantire che il calcolo sia gestito correttamente in ogni query (specialmente quando si tiene conto dell'ora legale)
  • Impedisci la scansione dell'intervallo di tutti gli indici di cui fa parte la colonna, poiché eseguirai un calcolo sulla colonna che forza le query a eseguire scansioni dell'indice anziché le ricerche (che sono generalmente più costose in quanto è necessario leggere ogni pagina di dati); questo è noto per non essere rilevante .
    • Modifica a causa di commenti: questo si applica se si sposta la conversione verso il basso nella query effettiva .
  • Utilizzando il concetto di avere a disposizione le date e gli orari UTC aggiuntivi, non c'è nulla che ti impedisca di prendere questo concetto e di estenderlo chiamando questo StandardisedDateKey, oppure CorporateHQDateKey, dove invece di una tabella di data UTC standardizzi in base ad altri standard concordati per le attività
  • Avere i due tipi di colonna separati (Local e UTC), consente il confronto side-by-side attraverso la distanza geografica. Pensa -> qualcuno in Australia inserisce un record con data e ora sia locale che UTC, qualcuno a New York legge il rapporto con la data e l'ora locale (Australia) e la rappresentazione di New York della data e ora UTC, vedendo così qualcosa la loro controparte australiana ha fatto durante la giornata (ora dell'Australia) avvenuta nel cuore della notte (ora di New York). Questo confronto di tempo è indispensabile nelle imprese multinazionali.

Perché usare separati Datee Timedimensioni anziché un singolo DateTime? Una tabella dei fatti può avere diverse date e può essere sommata la memorizzazione di due INT invece di una per ciascuna.
Jon of All Trades,

1
@Jon of All Trades: dimensioni separate di data e ora sono una best practice comune. Riduce la cardinalità della dimensione generale e, in pratica, spesso suddividiamo per data e ora, oppure filtriamo per data e quindi suddividiamo per ora.
Mitch Wheat,

0

Mi scuso in anticipo per la brevità di questa risposta e ho intenzione di elaborare quando non sono al lavoro.

Ci sono sicuramente vantaggi nell'avere tabelle di data e ora in quanto consentono una facile aggregazione dei dati. In molti casi è il modo più semplice di ordinare per mese o giorni lavorativi cose di quella natura. Tuttavia, ciò non sostituisce necessariamente l'utilità di un timestamp. Nel tuo caso particolare un timestamp UTC. Una volta che hai quel timestamp, tutto ciò che devi fare è cambiarlo in ora locale nel livello di report o presentazione. Per evitare scansioni di intervallo, assicurati di convertire anche l'intervallo di richieste in ora UTC.

Se hai altre domande o commenti sentiti libero di chiedere.


1
Questo non risponde alla domanda.
Mitch Wheat,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.