Articles Tagués ‘Dimension’

SCD et dimensions historisées

2 juillet 2011

Revenons un peu sur les bases des modèles de Kimball, autrement appelés modèles en étoile ou en flocon de neige (star-schema, snowflake-schema).

On distingue différentes façons de gérer les dimensions que l’on classe en types (les attributs essentiellement).

  • Type 1 : dès qu’un attribut de la dimension change, on met à jour le membre
  • Type 2 : si un attribut change, on crée une nouvelle entrée pour conserver l’historique des valeurs
  • Type 3 : une version hybride que je n’ai jamais vu une seule fois en prod (ni même en dev)

Pour les attributs de Type 2, il faudra gérer des marqueurs indiquant quelle est la valeur en cours. On peut utiliser un booléen ou des dates (la dernière étant à NULL).

 

Un exemple pour comprendre :

Dans un cube CRM, j’analyse des ventes par clients et par extension par les différentes caractéristiques de ceux-ci (nombre d’enfants, CSP, etc.).
Quand M. Moulin change de CSP, on souhaite tracer cet événement car on veut garder le fait que M. Moulin était “ouvrier qualifié” quand il a fait son premier achat en 2005 et que ses achats de 2010 sont sous la catégorie “commerçant”.
On crée donc une nouvelle ligne dans la dimension pour représenter ce nouveau M. Moulin.
En revanche, on ne souhaite n’avoir qu’un seul M. Moulin et ses différents achats si on regarde sur l’ensemble des années.
Et si par exemple M. Moulin devenait Mme Moulin (c’est rare mais ça peut arriver), on ne souhaite pas forcément historiser cette information. On changera le champ dans toutes les occurrences.

On a donc une table de dimension qui ressemble à cela :

CustomerID

FullName

CSP

IsCurrent

2345 Moulin Gérard Ouvrier Qualifié

0

16009 Moulin Gérard Commerçant

1

Et la table de faits comme ceci :

FactID

CustomerID

ProductID

DateKey

7 2345 1234 20050708
100004 16009 456 20100130

Analysis Services (ie. le cube) saura agréger les ventes de Monsieur Moulin mais aussi les ventes par CSP. Ce “doublon” dans la dimension n’est pas un problème.

Comment implémenter cela dans l’ETL :

En SSIS (et plus généralement dans les ETL), on utilise un composant appelé SCD (Slowly Changing Dimension / Dimension à variation lente) qui prend en charge la mise à jour de la dimension en fonction des types de ses attributs.

On a un assistant qui nous guide dans cette tâche et qui va tout gérer, y compris l’historisation en générant les tâches sous-jacentes

image

Dans le screenshot ci-dessus, on voit plusieurs sorties au SCD. C’est l’assistant qui a créé tous les composants en dessous en fonction du type des attributs.
Je vous conseille de les renommer (pour les logs) sauf que si vous rejouez l’assistant, il recréera les composants :/

La question des Inferred Member :

Une étape de l’assistant demande si on doit gérer les Inferred Members (désolé, je n’ai pas le traduction à portée de main). J’ai souvent des questions sur ce point.

C’est pour gérer ce qu’on appelle les “early arriving fact”. En langage clair, ce sont des membres de la dimension qui ont été insérés par un autre moyen (souvent des membres créés à la volée lors de l’insertion des faits pour ne pas lever d’erreur et perdre d’information). Cette gestion évitera qu’au prochain passage du SCD, quand la ligne viendra de la source principale de recréer une ligne d’historique inutile.

Personnellement, je ne l’utilise jamais et je ne suis jamais tombé sur un DataWarehouse utilisant ce concept.

A surveiller :

Attention aux performances. Tout système décisionnel doit gérer des dimensions à variation lente mais c’est souvent un point noir dans le process.

En effet, pour chaque ligne d’entrée, une requête ramenant la ligne est effectuée pour faire la comparaison. Quelques tips :

  • faire de l’incrémental (CDC, champ “date de modification”, etc.)
  • mettre l’index Clustered sur la Business Key
  • ne pas historiser (Tire la langue)

Un point sur la conception :

Lors de la conception de la dimension, quand on fait le choix de l’historisation, il faut être vigilant.

Si vous demandez à l’utilisateur ce qu’on doit historiser, il répondra : “TOUT”. On connait l’adage, “qui peut le plus, peut le moins” mais il faut néanmoins raisonner tout cela car on peut vite tomber sur une usine à gaz.

Y’a t-il vraiment une réalité d’analyse derrière ?

N’oubliez pas que la clé d’un projet de business intelligence est la modélisation de l’analyse (approche top-down, approche MDM, etc.).
La phase d’interview doit être vigilante à ces problématiques “techniques” car ce n’est pas parce que c’est supporté que c’est bon de le mettre.

On sera donc vigilant à la cardinalité. Si votre dimension à 40 attributs et que la fréquence de changement est haute, vous risquez d’avoir énormément de lignes dans la table de dimension.
Je suis tombé une fois sur une dimension ou au moins un des attributs changeait tous les jours. A ce niveau, ce n’est pas une dimension historisée mais des faits.

Un dernier tip pour la route :

Pour la développeur qui doit ouvrir le package longtemps après la conception ou bien le consultant qui l’ouvre pour faire une analyse ou un optimisation, il peut arriver (si le modèle de données est désynchroniser) que le composant perdre sa configuration. C’est rare mais ça m’est arrivé (de moins en moins avec les versions qui avancent).

Pour ne pas devoir fouiller dans le XML du DTSX, je demande à mes équipes de documenter le SCD avec une annotation. Voici un exemple ci-dessous.

image

 

Pour finir, les problèmes :

Dans le post suivant, je parlerai d’un petit problème qui existe avec le SCD, les dimensions de Type 2 et les marqueurs de type date

(et je ne parle pas du fait que si vous rejouez l’assistant, il recrée les composants sous-jacent et donc casse tout votre nommage Fâché)

Plusieurs membres par défaut

16 avril 2011

Si vous cherchiez à utiliser un Set (ensemble de membres) comme sélection par défaut dans une dimension, autant vous le dire tout de suite, ce n’est pas possible.
Vous noterez que DefaultMember (membre par défaut) est au singulier Clignement d'œil.

image

Donc comment faire pour avoir plusieurs membres (pas de mauvais jeu de mots…) ?

La solution passe par la hiérarchisation de votre dimension. Mettre une hiérarchie permet d’ajouter des nœuds intermédiaires regroupants plusieurs membres enfants.

Ex : vous avez une dimension [Catégorie] et vous voulez avoir comme membre par défaut les catégories [Catégorie].[Vente Produits] et [Catégorie].[Divers]. Il faut donc utiliser par exemple [Catégorie].[Hiérarchie].[Ventes] qui contiendra nos 2 catégories visées.

Et en utilisant un Named Set dans les calculs du cube ? On peut être tenté d’en créer un et de l’utiliser.

CREATE STATIC HIDDEN SET CURRENTCUBE.[DefaultCat] AS {[Catégorie].[Vente Produits] , [Catégorie].[Divers]} 

Sauf qu’un Named Set est par définition un Set et non un membre. En plus le Named Set se trouve sur le cube et pas sur la dimension. Même avec un ALTER CUBE, vous aurez une erreur (La fonction  attend une expression de hiérarchie pour l’argument. Une expression d’ensemble de tuples a été utilisée).

ALTER CUBE Vente  UPDATE DIMENSION [Catégorie].[Catégorie], DEFAULT_MEMBER = [MonNamedSet] 

Dimension Scenario

19 décembre 2010

image

 

Je rencontre fréquemment en consulting des problématiques relatives aux budgets et/ou aux prévisionnels à intégrer dans un cube.

Comme souvent en décisionnel, il y a de nombreuses façons de traiter (concevoir) ce type de fonctionnalité et le but de ce post n’est en aucun cas de rédiger un état de l’art sur le sujet.

Je propose en règle générale 2 approches :

  • utilisation d’une table de budgets
  • utilisation d’une dimension scénario

Je vais passer vite sur la première approche puisqu’elle consiste à ajouter des mesures représentant les budgets. Bien souvent, on a un table de faits dédiée (et donc un groupe de mesure). On peut donc jouer avec les mesures Ventes et Ventes prévues par exemple.

J’aime cette approche car elle permet d’avoir une granularité différente de la table de faits principale (qu’on résout par des Cube Calculation mais c’est une autre histoire Smile).

La dimension Scenario

L’idée de cette approche consiste à créer une nouvelle dimension qui contient les scénarios de travail comme par exemple Courant (Actual), Budget 1, Budget 2, Prévisionnel (Forecast), etc.

On ajoute donc une clé dans la table de fait pour le scénario pour gérer la nouvelle dimension. Cela permet d’avoir une infinité de scénarii, utile en période de planification budgétaire (d’ailleurs les utilisateur de feu Planning Server connaissent très bien cette approche).

Scenarii

C’est cette technique qui est utilisée dans la réalisation de cubes comptable.

Evidemment, on utilisera un Default Member sur cette dimension afin de ne pas perturber l’usage en affichant naturellement le scénario courant.

Remplissage d’une dimension temps

19 décembre 2010

Pour générer et alimenter automatiquement une table de dimension temps, il  existe une option dans l’assistant de création des dimensions de BIDS.

Créez une nouvelle dimension en suivant les étapes suivantes :

Assistant dimension temps - step 1
Choix de la bonne option

Assistant dimension temps - step 2
Choix de la plage de dates

Assistant dimension temps - step 3

Assistant dimension temps - step 4
Démarrage de l’assistant de génération de la table dans le DataWarehouse

Assistant dimension temps - step 5
Ne pas oublier de choisir l’option Populate pour générer les enregistrements

A ce stade, la table est générée et alimentée.

Pour anticiper le passage en production, je mets un profiler sur ma base de développement pour récupérer le script de remplissage (populate).

Je refais la même manipulation pour mettre à jour la dimension temps. En effet, on ne mets pas toujours toutes les dates possibles dans la dimension et je prends l’habitude de mettre un reminder fin novembre pour alimenter l’année qui arrive. (voire faire un script qui la génère automatiquement).

 

PS : merci Philippe de l’équipe DGD de Bewise pour les screenshots.

Tuning des attributs de dimension dans Analysis Services

21 mai 2010

 

Les attributs d’une dimension dans un cube servent à la base à analyser les données selon les valeurs qu’ils contiennent. Par exemple, dans une dimension produit, on peut avoir des attributs comme la couleur, le poids, la gamme, le nom du designer qui l’a créé, etc.

Dans la vraie vie, une dimension peut contenir un grand nombre d’attributs. Le problème est que souvent, certains attributs n’ont rien à voir avec de l’analyse. Par exemple, un attribut Adresse dans une dimension client n’est pas un bon candidat pour l’analyse (et je parle bien de l’adresse du genre “3 rue des macarons cuits”, pas de la ville ou du code postal).

image

Néanmoins, on trouve souvent ce genre d’attributs à des fins de présentation dans un rapport (pour du publipostage ou de l’export par exemple).

Mon premier avis serait d’orienter ce genre de restitution de données vers une base de production (ou tout du moins dans une base relationnelle) comme source de données et non un cube mais ce n’est pas toujours possible.

L’approche que j’utilise est la suivante. Je catégorise avec mon client les attributs :

  • Attribut d’analyse : utilisé pour ventiler les mesures
  • Attribut intermédiaire : attribut technique utilisé dans une Referenced Dimension Usage par exemple
  • Propriété simple : utilisé pour afficher des méta-données sur le client

En fonction de ma classification, je configure les attributs différemment pour optimiser mon cube :

image

Enabled

Visible

OptimizedState

Attribut d’analyse

True

True

FullyOptimized

Attribut intermédiaire

True

False

NotOptimized

Propriété

False

N/A

NotOptimized

Il y a toutefois encore un problème à résoudre. En effet, le fait de mettre AttributeHierarchyEnabled à false, empêche de voir la propriété dans les assistants d’un outil comme Report Builder.

En effet, en requêtage MDX, on récupère un CellSet qui peut contenir, si on les demande dans la requête, les méta-données mais il faut que le client OLAP sache les exploiter correctement.

Par exemple, Excel (2007+) sait les demander et les afficher nativement.

image

Dans Report Builder, on devra passer par un membre calculé pour remonter la propriété comme une mesure avec une expression comme celle-ci.

[Tiers].CurrentMember.Properties(“Adresse”)

La méthode est décrite dans ce post :
 http://blog.djeepy1.net/2009/01/27/report-builder-2-0-creer-un-membre-calcule-sans-passer-par-ssas/


Suivre

Get every new post delivered to your Inbox.

Joignez-vous à 203 followers