📊 Data

data-dimensional-modeling

Modélisation dimensionnelle pour le data warehousing — schéma en étoile, flocon, tables de faits et dimensions, slowly changing dimensions.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- data-dimensional-modeling --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } data-dimensional-modeling -Launch"

🚀 Déjà installé ?

claude "/data-dimensional-modeling"

Ou tapez /data-dimensional-modeling dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

schéma en étoilestar schematable de faitsdimensiondata warehouseSCDslowly changing dimensionmodélisation dimensionnelle

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/data-dimensional-modeling ~/.claude/skills/

Payload du plugin : skills/data-dimensional-modeling · source éditable : data-skills/dimensional-modeling

📖 Manuel

Modélisation Dimensionnelle

Workflow — 4 décisions dans l'ordre

1. Identifier le processus métier

Choisir UN processus à la fois (ventes, commandes, facturation, trafic web). Ne pas mélanger deux processus dans une même table de faits à ce stade.

2. Définir le grain

La décision la plus critique. "1 ligne = ?" doit s'énoncer en une phrase.

GrainExemple
Grain fin (transactionnel)1 ligne par ligne de commande
Grain moyen1 ligne par commande
Grain agrégé1 ligne par client par mois
Règle : toujours choisir le grain le plus fin techniquement supportable.
Les agrégats peuvent toujours être calculés à la requête ; l'inverse est impossible.

3. Identifier les dimensions

Questions guides : Qui ? Quoi ? Où ? Quand ? Comment ? Chaque dimension répond à l'une de ces questions pour décrire le fait.

4. Identifier les mesures (faits)

Ne retenir que les mesures numériques cohérentes avec le grain défini. Classer chaque mesure : additive / semi-additive / non-additive.

AdditivitéDéfinitionExemple
AdditiveSomme valide sur toutes dimensionsQuantité vendue, chiffre d'affaires
Semi-additiveSomme valide sur certaines dimensions seulementSolde de compte (pas sur le temps)
Non-additivePas de somme utileTaux, ratios, prix unitaire

Schéma en étoile — Structure SQL

-- Table de faits
CREATE TABLE fact_sales (
    sale_key        BIGINT IDENTITY PRIMARY KEY,
    date_key        INT NOT NULL REFERENCES dim_date(date_key),
    product_key     INT NOT NULL REFERENCES dim_product(product_key),
    customer_key    INT NOT NULL REFERENCES dim_customer(customer_key),
    store_key       INT NOT NULL REFERENCES dim_store(store_key),

    -- Mesures additives
    quantity        INT            NOT NULL,
    unit_price      DECIMAL(10,2)  NOT NULL,
    discount_amount DECIMAL(10,2)  NOT NULL DEFAULT 0,
    net_amount      DECIMAL(10,2)  NOT NULL,
    tax_amount      DECIMAL(10,2)  NOT NULL,
    total_amount    DECIMAL(10,2)  NOT NULL,

    -- Clés dégénérées (identifiants source sans dimension propre)
    invoice_number  VARCHAR(50),
    line_number     INT
);

-- Dimension Date (pré-remplie, jamais via ETL en temps réel)
CREATE TABLE dim_date (
    date_key      INT         PRIMARY KEY,  -- Format YYYYMMDD
    full_date     DATE        NOT NULL,
    day_of_week   INT         NOT NULL,     -- 1=Lundi ... 7=Dimanche
    day_name      VARCHAR(10) NOT NULL,
    day_of_month  INT         NOT NULL,
    week_of_year  INT         NOT NULL,
    month_number  INT         NOT NULL,
    month_name    VARCHAR(10) NOT NULL,
    quarter       INT         NOT NULL,
    year          INT         NOT NULL,
    is_weekend    BIT         NOT NULL,
    is_holiday    BIT         NOT NULL,
    fiscal_year   INT,
    fiscal_quarter INT
);

Remplir dim_date en SQL (script one-shot)

-- Génère toutes les dates entre deux bornes
WITH dates AS (
    SELECT CAST('2010-01-01' AS DATE) AS d
    UNION ALL
    SELECT DATEADD(DAY, 1, d) FROM dates WHERE d < '2030-12-31'
)
INSERT INTO dim_date (date_key, full_date, day_of_week, day_name,
                      day_of_month, week_of_year, month_number, month_name,
                      quarter, year, is_weekend)
SELECT
    CONVERT(INT, FORMAT(d, 'yyyyMMdd')),
    d,
    DATEPART(WEEKDAY, d),
    DATENAME(WEEKDAY, d),
    DAY(d),
    DATEPART(WEEK, d),
    MONTH(d),
    DATENAME(MONTH, d),
    DATEPART(QUARTER, d),
    YEAR(d),
    CASE WHEN DATEPART(WEEKDAY, d) IN (1,7) THEN 1 ELSE 0 END
FROM dates
OPTION (MAXRECURSION 10000);

Slowly Changing Dimensions (SCD)

Critères de choix

TypeConserver l'historique ?Volume deltaÀ utiliser si…
Type 1NonFaibleCorrection d'erreur, attribut sans valeur analytique (ex: code postal format)
Type 2Oui, completMoyen-élevéSegment client, territoire vendeur, catégorie produit
Type 3Partiel (1 seule transition)FaibleRéorganisation connue à l'avance avec comparaison avant/après
Type 4 (mini-dimension)Oui, séparéAttributs très volatilsProfil comportemental changeant fréquemment
Type 6 (hybride 1+2+3)Oui + snapshot courantComplexeBesoin de navigation historique ET valeur courante dénormalisée

SCD Type 2 — Pattern complet

CREATE TABLE dim_customer (
    customer_key   INT          IDENTITY PRIMARY KEY,  -- Surrogate key
    customer_id    VARCHAR(50)  NOT NULL,               -- Business key (NK)
    name           VARCHAR(200) NOT NULL,
    email          VARCHAR(200),
    city           VARCHAR(100),
    segment        VARCHAR(50),

    effective_date DATE         NOT NULL,
    expiration_date DATE        NOT NULL DEFAULT '9999-12-31',
    is_current     BIT          NOT NULL DEFAULT 1
);

-- ETL : mise à jour SCD Type 2
BEGIN TRANSACTION;

-- Étape 1 : expirer l'enregistrement actuel
UPDATE dim_customer
SET    expiration_date = CAST(GETDATE() AS DATE),
       is_current      = 0
WHERE  customer_id = 'CUST-123'
  AND  is_current  = 1;

-- Étape 2 : insérer la nouvelle version
INSERT INTO dim_customer (customer_id, name, email, city, segment, effective_date)
VALUES ('CUST-123', 'Jean Dupont', 'jean@new.com', 'Lyon', 'Premium', CAST(GETDATE() AS DATE));

COMMIT;

-- Requête sur une période historique
SELECT f.total_amount, c.segment
FROM   fact_sales f
JOIN   dim_customer c ON c.customer_key = f.customer_key
                      AND c.effective_date <= f.sale_date
                      AND f.sale_date < c.expiration_date;

Types de tables de faits

TypeGrainCas d'usage
Transactionnelle1 ligne par événement atomiqueVentes, clics, transactions
Snapshot périodique1 ligne par entité par périodeSolde mensuel, stock fin de journée
Snapshot cumulatif1 ligne par cycle de viePipeline commande (créée → validée → expédiée → livrée)
Sans faits (factless)Intersection sans mesurePrésence à un événement, éligibilité à une promotion

Snapshot cumulatif — colonnes types

CREATE TABLE fact_order_pipeline (
    order_key         INT     PRIMARY KEY,
    order_id          VARCHAR(50),
    -- Une date_key par étape
    created_date_key  INT     REFERENCES dim_date(date_key),
    approved_date_key INT     REFERENCES dim_date(date_key),
    shipped_date_key  INT     REFERENCES dim_date(date_key),
    delivered_date_key INT    REFERENCES dim_date(date_key),
    -- Lag entre étapes (recalculé à chaque mise à jour)
    days_to_approve   INT,
    days_to_ship      INT,
    days_to_deliver   INT,
    order_amount      DECIMAL(12,2)
);

Schéma flocon (snowflake) — quand l'utiliser

Normaliser une dimension (ex: dim_product → dim_category → dim_department) :

Règle 2026 : préférer le star schema sauf si le volume de la dimension est > 10M lignes et que les attributs normalisables sont très stables. Les outils BI modernes (Power BI, Tableau, Looker) sont optimisés star.

Anti-patterns et garde-fous

Anti-patternSymptômeCorrection
Grain mixteMesures incomparables dans une même factSéparer en deux tables de faits
Clé métier comme FKJOIN lent, problèmes SCDToujours utiliser les surrogate keys
Dimension fourre-toutdim_misc, dim_attributes avec 80 colonnesDécomposer en dimensions thématiques
Mesure non-additive stockée bruteRequêtes fausses (SUM de taux)Stocker numérateur + dénominateur, calculer le ratio en vue
SCD Type 2 sur toutTable de 100M lignes pour une dim de 10k clientsChoisir SCD Type 1 pour attributs sans valeur historique
dim_date absenteFiltres dates via CAST sur la factToujours créer et pré-remplir dim_date
NULL en FKRuptures de jointure silencieusesCréer une ligne "inconnu" (key = -1) dans chaque dimension

Bonnes pratiques 2026