0

Je suis un peu nouveau dans le développement BI/l'entreposage de données, mais je suis confronté à l'ancien dilemme lent des dimensions changeantes. J'ai beaucoup lu sur les types et la théorie, mais j'ai trouvé peu de choses en termes de ce que je considère comme les requêtes SELECT les plus courantes contre ces implémentations.Modification lente des dimensions - implémentation exacte de la requête SQL pour récupérer les données correctes

Je vais garder mon exemple simple. Supposons que vous ayez quatre raisons de vente: Est, Ouest, Nord et Sud. Vous avez un groupe de vendeurs qui effectuent des ventes quotidiennes et (peut-être une fois par an) sont réaffectés à une nouvelle région.

Vous aurez des données brutes comme les suivantes:

name; sales; revenue; date 
John Smith; 10; 5400; 2015-02-17 

Vous avez des données comme ça tous les jours.

Vous pouvez également avoir une table dimensions comme suit, d'abord:

name; region 
John Smith; East 
Nancy Ray; West 
Claire Faust; North 

Ainsi, le directeur des ventes veut connaître le chiffre d'affaires mensuel pour la région Est en mai 2015. Vous exécuterez une requête:

SELECT region, month(date), sum(revenue) 
from Fact_Table inner join Dim_Table on name = name 
where region = East and date between .... 
[group by region, month(date)] 

Vous avez l'idée. Ignorons que j'utilise des clés naturelles à la place des clés de substitution; J'utiliserais clairement des clés de substitution.

Maintenant, de toute évidence, les vendeurs peuvent déplacer des régions en milieu d'année. Ou au milieu du mois. Vous devez donc créer un type SCD afin d'exécuter cette requête. Pour moi, le type 2 est le plus logique. Donc disons que vous l'appliquez. Dites John Smith a changé de région de l'Est à la région de l'Ouest le 15 mai 2015. Vous implémentez le tableau suivant:

name; region; start_date; end_date 
John Smith; East; 2015-01-01; 2015-05-15 
John Smith; West; 2015-5-15; 9999-12-31 

Maintenant, le directeur des ventes pose la même question. Quel est le revenu total des ventes de l'Est pour mai 2015? Ou encore, montrez-moi les totaux par région par mois pour toute l'année. Comment structureriez-vous la requête?

SELECT region, month(date), sum(reveneue) 
from Fact_Table inner join Dim_Table 
on name = name 
and date between start_date and end_date 
group by region, month(date) 

Est-ce que cela donnerait les bons résultats? J'imagine que ça pourrait être ... ma question est peut-être plus du genre --- d'accord, supposons maintenant que vous avez 1 million d'enregistrements dans la table de faits ... cette jointure interne serait-elle vraiment inefficace, ou y at-il un moyen plus rapide ce résultat? Serait-il plus logique d'écrire la SCD (comme la région) directement dans une table de faits 'dénormalisée' --- et quand la dimension change, peut-être mettre à jour rétroactivement une semaine ou deux de régions Fact record '?

+0

Je ne pense pas que votre exemple aide, comme la région et par personne pour les ventes serait clairement différentes dimensions. La structure que vous définissez rend très difficile la structuration efficace de la requête pour la question de base que vous souhaitez poser, ce qui indique que le modèle est erroné. Dès que vous avez besoin d'une requête complexe, vous devez réévaluer votre structure dimensionnelle. –

+0

Il s'agit d'un exemple assez courant dans la plupart des documents SCD, en fait. Mon exemple de «vie réelle» est à peu près le même. Une liste de noms appartenant à divers bureaux régionaux (USA vs. Europe vs. Asia) ... certaines applications n'ont pas de point de données 'région' direct ... ou même de point de données 'département' ... ceux-ci sont codés séparément . Tout ce que vous avez est le nom de l'employé de l'application. La «référence principale» renvoyant un tel employé à un bureau régional, ou un département (marketing vs service à la clientèle) ... est basée sur le temps. Je ne comprends pas comment vous dites que le modèle de données est erroné. – user45867

+0

Essentiellement, le seul lien, dans mon exemple, du revenu vers la région doit TOUJOURS passer par l'employé d'abord, comme une circonstance des données. Cela peut aider à comprendre si vous remplacez «Région» par «département». – user45867

Répondre

1

Votre concept est correct si les besoins de votre entreprise ont une hiérarchie Region-> Seller, comme indiqué dans votre exemple.

La performance de votre requête actuelle peut être difficile, mais elle sera améliorée par l'utilisation de clés de dimension et d'attributs appropriés.

Utilisez une hiérarchie de dimension de date incluant date-> Month et vous pourrez éviter la requête de plage.

Utilisez des nombres entiers, des clés de substitution dans les deux dimensions et votre performance d'indexation s'améliorera.

un million de lignes est minuscule, vous n'avez des problèmes de performance sur tous les SGBD compétentes :)

+0

Oui, cela a du sens - je garderai ces conseils à l'esprit. Que voulez-vous dire par hiérarchie de dimension de date? Vous voulez dire dans la table de dimension avec les dates 'effectives' --- écrire le mois dans la table aussi bien au moment de l'insertion/écriture de la table? – user45867

+0

Pour les dates, vous devriez avoir une dimension qui est quelque chose comme: dim_date (id, date_business_key, jour, mois, année, day_of_week, MONTH_NAME, etc.) Votre table de fait ne doit contenir une référence clé étrangère à la dim_date table. Pour trouver les ventes dans un mois donné, interrogez la jointure de votre fact + dim_date, où l'année et le mois sont vos valeurs requises. –

+0

Cela est logique sauf que, si un vendeur était seulement dans l'Est pendant une demi-mois, du 1er juin au 15 juin .... alors additionner le 'total' pour la gamme Est nécessite encore de diviser les données à la date de la granularité , pas simplement le mois. – user45867