Gestion des fuseaux horaires dans le Data Mart / Warehouse


12

Nous commençons à concevoir les blocs de construction d'un magasin de données / entrepôt et nous devons être en mesure de prendre en charge tous les fuseaux horaires (nos clients viennent du monde entier). De la lecture des discussions en ligne (et dans les livres), une solution courante semble être d'avoir une dimension de date et d'heure distincte ainsi qu'un horodatage dans les tables de faits.

Cependant, la question à laquelle j'ai du mal à répondre est de savoir à quoi me servent réellement les dimensions de date et d'heure compte tenu de mes exigences de fuseau horaire dynamique. Une dimension de temps a un peu plus de sens mais j'ai du mal avec la dimension de date. Une approche de conception générale pour une dimension de date comprend généralement des propriétés telles que le nom du jour, le jour de la semaine, le nom du mois, etc. Le problème que j'ai avec tout cela est que 23h00 le mardi 31 décembre 2013 à UTC est mercredi , 1er janvier 2014 dans tous les fuseaux horaires postérieurs à UTC + 2.

Donc, si je dois faire toutes ces conversions de fuseau horaire sur chaque requête (et rapport), quel est l'intérêt d'avoir et de stocker ces propriétés que je n'utiliserai probablement jamais (semble-t-il)? Certaines personnes suggèrent d'avoir des lignes de faits pour chaque fuseau horaire, mais cela me semble ridicule. Nous devons être en mesure de stocker des millions d'enregistrements chaque mois.

D'autres suggèrent d'avoir une table de pont de fuseau horaire qui, bien que logique, semble également être une complexité supplémentaire et des jointures supplémentaires pour accomplir quelque chose que mes applications et rapports clients devraient facilement être en mesure de comprendre à partir d'une date (les rapports seront principalement basés sur le Web où il existe une myriade de bibliothèques pour aider à la conversion, l'affichage et le formatage des dates).

La seule chose à laquelle je peux penser est la facilité et éventuellement les performances du regroupement par date et heure, mais à quel point une pratique est mauvaise de regrouper par partie de date (nous utilisons MS SQL mais nous interrogerons des millions de lignes) ou devrions-nous envisager juste des dimensions de date et d'heure extrêmement simples avec pas beaucoup plus que les nombres d'heure, de jour, de mois et d'année, car la plupart des littéraux tels que lundi ne signifieraient pas grand-chose lorsque les fuseaux horaires entrent en jeu?


1
Je pense que ce que vous recherchez est le type de données datetimeoffset, puis stockez toutes les dates dans leur représentation UTC. Ensuite, lorsque vous devez extraire les données, vous interrogez les données dans leur valeur UTC et laissez le client les représenter dans son heure locale.
Allan S. Hansen

6
Je ne vois aucune raison pour laquelle je voudrais stocker la date indépendamment du temps. Stockez le tout en tant que datetime UTC et laissez la couche de présentation se soucier de la localisation.
billinkc

1
Je suis d'accord avec @billinkc. Je ne sais pas quel avantage vous gagneriez à stocker la date et l'heure séparément lorsque vous finiriez par les remonter constamment pour faire la conversion du fuseau horaire.
mmarie

2
@billinkc: "Je ne vois aucune raison pour laquelle je voudrais stocker la date indépendamment du temps." - Je peux. Chaque fois que vous construisez un cube hors de l'entrepôt. Le fait d'avoir des dimensions de date et d'heure distinctes est courant et constitue la meilleure pratique.
Mitch Wheat

@MitchWheat Pourriez-vous m'aider à comprendre cela (peut-être que vous composez une réponse)? Je suis une entreprise adulte avec des ventes mondiales et à 23h00 GMT, j'ai une forte augmentation des ventes. Je traîne ma trancheuse dans le rapport et bien sûr, dans les fuseaux horaires de l'Est et du Centre des États-Unis, je pourrais avoir des ventes pendant que les gens ramassent des boissons emballées sur le chemin du retour, mais il est 03h30 en Inde, personne ne ramasse Kingfisher à cette heure et 6 heures du matin à Perth. Vous êtes tous puissants, mais qui se brosse les dents avec VB? Au lieu de cela, les gens achètent de l'alcool après le travail, donc 1700ish, mais je dois ensuite m'inquiéter des limites de date
billinkc

Réponses:


7

D'abord...

La séparation Datime/Timeen une Datedimension et une Timedimension est définitivement la voie à suivre.

Pour gérer plusieurs fuseaux horaires, vous devez dupliquer le DateKeyet le TimeKeyafin d'avoir les éléments suivants:

  • LocalDateKey
  • LocalTimeKey
  • UtcDateKey
  • UtcTimeKey

Vous dites...

Le problème que j'ai avec tout cela est que 23h00 le mardi 31 décembre 2013 à UTC est le mercredi 1er janvier 2014 dans tous les fuseaux horaires qui sont après UTC + 2.

En ayant les 4 colonnes que j'ai énumérées ci-dessus, vous pourrez joindre la table de faits à la dimension Date et / ou Heure à l' aide des alias de table (dans la terminologie Kimball, ces tables de dimensions aliasées sont appelées "Dimensions de jeu de rôle"), donc vous auriez quelque chose comme ceci:

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

En terminant ...

Comme vous créez un magasin de données et non une base de données OLTP, la génération des heures locales et utc doit être effectuée dans votre ETL , PAS dans les applications côté client pour les raisons suivantes (à l'exception de la localisation de l'heure UTC dans point de vue du lecteur de rapport):

  • Le fait que le calcul réside dans toutes les requêtes impose une charge de performance supplémentaire, multipliée par le nombre de fois que vous devez exécuter ladite requête pour tous les rapports que vous possédez (cela est important lors de la lecture de millions de lignes)
  • Charge supplémentaire pour garantir que le calcul est correctement maintenu dans chaque requête (en particulier lorsque vous prenez en compte l'heure d'été)
  • Empêchez l'analyse de plage des index dont fait partie la colonne, car vous effectuerez un calcul sur la colonne qui obligera les requêtes à effectuer des analyses d'index au lieu de recherches (qui sont généralement plus coûteuses car chaque page de données doit être lue); cela est connu comme étant non sargable .
    • Modifier en raison de commentaires: cela s'applique si vous poussez la conversion vers le bas dans la requête réelle .
  • En utilisant le concept de disponibilité des dates et heures UTC supplémentaires, rien ne vous empêche de prendre ce concept et de l'étendre en l'appelant StandardisedDateKey, ou CorporateHQDateKey, au lieu d'un tableau de dates UTC, vous standardisez en fonction d'une autre norme convenue par l'entreprise
  • Le fait d'avoir les deux types de colonnes séparés (Local et UTC), permet une comparaison côte à côte sur une distance géographique. Pensez -> quelqu'un en Australie entre un enregistrement horodaté avec Local et UTC, quelqu'un à New York lit le rapport avec la date et l'heure locales (Australie) et la représentation new-yorkaise de la date et de l'heure UTC, voyant ainsi que quelque chose leur homologue australien a fait au milieu de la journée (heure de l'Australie) est arrivé au milieu de la nuit leur heure (heure de New York). Cette comparaison du temps est indispensable dans les entreprises multinationales.

Pourquoi utiliser des dimensions séparées Dateet Timeau lieu d'une seule DateTime? Une table de faits peut avoir plusieurs dates, et le stockage de deux INT au lieu d'un pour chacun peut s'additionner.
Jon of All Trades

1
@Jon of All Trades: des dates et heures différentes sont une bonne pratique courante. Cela réduit la cardinalité de la dimension globale et, dans la pratique, nous découpons souvent par date et heure, ou filtrons par date, puis par tranche.
Mitch Wheat

0

Je m'excuse à l'avance pour la brièveté de cette réponse et je prévois de préciser quand je ne suis pas au travail.

Il y a très certainement des avantages à avoir des tables de date et d'heure car elles permettent une agrégation facile de vos données. Dans de nombreux cas, c'est le moyen le plus simple de trier par mois ou jours ouvrables des choses de cette nature. Cependant, cela ne remplace pas nécessairement l'utilité d'un horodatage. Dans votre cas particulier, un horodatage UTC. Une fois que vous avez cet horodatage, tout ce que vous avez à faire est de le changer en heure locale dans la couche de rapport ou de présentation. Afin d'éviter les analyses de plage, assurez-vous de convertir également votre plage de demandes en heure UTC.

Si vous avez d'autres questions ou commentaires, n'hésitez pas à demander.


1
Cela ne répond pas à la question.
Mitch Wheat
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.