La tentation du débutant : aplatir toutes les données dans un immense fichier avec une RechercheV par-ci, une RechercheV par-là. Ça marche… jusqu'à ce que ça casse. Les données se dupliquent, les mises à jour deviennent un cauchemar, et le moindre changement oblige à tout refaire.
Power BI travaille autrement : on garde les tables séparées et on les relie. La table de faits contient les événements (les ventes), les tables de dimensions contiennent le contexte (qui, quel canal, quand). On croise à la demande, sans jamais dupliquer.
Relier deux tables, c'est déclarer qu'une colonne de l'une correspond à une colonne de l'autre : la clé. Sur TheLook, la table de faits porte un user_id ; la table clients porte aussi un user_id. On relie les deux sur cette clé, et Power BI sait recoller le bon client à chaque ligne de vente.
Les pays « France » et « Belgique » ci-dessus illustrent le principe (les vraies valeurs viennent de la colonne country). Le point important : un même user_id apparaît une seule fois côté clients, mais plusieurs fois côté ventes — c'est la cardinalité.
La cardinalité décrit combien de lignes se correspondent de chaque côté. Sur TheLook, un client peut passer plusieurs commandes : une ligne côté clients, plusieurs côté ventes. C'est une relation un-à-plusieurs (1:N) — la plus courante et la plus saine. La dimension est du côté « 1 », les faits du côté « N ».
| Cardinalité | Sens | À faire |
|---|---|---|
| 1:N | Une dimension, plusieurs faits (1 client → N ventes) | La norme. C'est ce qu'on veut. |
| 1:1 | Une ligne d'un côté = une ligne de l'autre | Rare. Souvent signe que les deux tables devraient être fusionnées. |
| N:N | Plusieurs des deux côtés | À éviter : source de doublons et de chiffres faux. On la contourne par une table de dimension propre. |
user_id doit apparaître une seule fois dans SRC_USERS.
Deux réflexes simples sur TheLook pour s'assurer que user_id est unique dans SRC_USERS :
user_id distincts (Nombre de valeurs distinctes). S'ils diffèrent, il y a des doublons.Corriger un doublon se fait en amont, dans Power Query (supprimer les doublons sur la colonne clé), pas en bricolant le visuel après coup. On répare la source, jamais le symptôme.
| Un seul fichier plat | Schéma en étoile | |
|---|---|---|
| Données | Dupliquées à chaque ligne (le nom du client répété partout) | Stockées une fois, reliées par une clé |
| Mise à jour | Fragile : une correction à répercuter partout | Un seul endroit à changer |
| Calculs | Lourds, risque de doubles comptages | Justes et rapides |
| Évolutivité | Tout casse quand on ajoute une source | On branche une dimension de plus, sans toucher au reste |
Le canal (traffic_source) vit dans la table de faits, mais pour en faire un axe d'analyse propre et le relier plus tard au marketing et au budget, on crée une petite table de dimension dédiée. Dans Power Query, une requête vide avec ce code M :
let Source = Table.FromRows( { {"Search"}, {"Organic"}, {"Email"}, {"Display"}, {"Facebook"} }, type table [Canal = text] ) in Source
On relie ensuite DIM_CANAL[Canal] à SRC_ORDER_ITEMS[traffic_source] en 1:N. Désormais, filtrer sur un canal filtre toutes les ventes de ce canal.
Search, Organic, Email, Display, Facebook. « search » ≠ « Search ». La moindre variation empêche la relation de fonctionner et fait disparaître des lignes du résultat. C'est LA source d'erreur silencieuse à traquer.
Une fois les dimensions reliées à la table de faits, on obtient une étoile : les faits au centre, les dimensions autour, chacune reliée par une clé en 1:N. Aucune dimension n'est reliée à une autre directement — tout passe par le centre.
Le sens du filtre va de la dimension vers les faits : choisir un client, un canal ou une date filtre les ventes correspondantes, et toutes vos mesures (CA Réel, Marge, CAC…) se recalculent dans ce contexte. C'est exactement pour ça qu'on a séparé les tables.
month dans la table de faits). Un modèle lisible, c'est un modèle où l'utilisateur ne voit que ce qui l'aide à décider.