0Pricing
SQL Academy · Leçon

Tables de faits et de dimensions

Les éléments fondamentaux d’un entrepôt de données.

Tables de faits et de dimensions est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.

Qu’est-ce qu’un entrepôt de données ?

Un entrepôt de données est un référentiel central conçu pour la production de rapports et les requêtes analytiques. Contrairement à une base de données transactionnelle, optimisée pour des écritures rapides, un entrepôt est réglé pour effectuer rapidement des lectures sur de grands volumes de données historiques.

La manière la plus courante d’organiser un entrepôt consiste à utiliser un schéma en étoile, qui répartit les données entre deux types de tables : les tables de faits et les tables de dimensions.

Définition des tables de faits

Une table de faits stocke des événements mesurables et quantitatifs : les éléments que vous souhaitez analyser. Chaque ligne représente une occurrence d’un événement métier, comme une vente, la consultation d’une page Web ou un ticket d’assistance.

Les tables de faits sont généralement longues (beaucoup de lignes) et étroites (peu de colonnes), la plupart des colonnes étant soit des clés étrangères vers des tables de dimensions, soit des mesures numériques comme quantity ou revenue.

CREATE TABLE fact_sales (
  sale_id      SERIAL PRIMARY KEY,
  date_key     INT NOT NULL,
  product_key  INT NOT NULL,
  customer_key INT NOT NULL,
  store_key    INT NOT NULL,
  quantity     INT NOT NULL,
  unit_price   NUMERIC(10, 2) NOT NULL,
  total_amount NUMERIC(12, 2) NOT NULL
);

Définition des tables de dimensions

Une table de dimensions stocke des attributs descriptifs qui donnent du contexte à chaque fait. On peut citer la dimension produit (nom, catégorie, marque) ou la dimension date (jour, mois, trimestre, année).

Les tables de dimensions sont généralement courtes (moins de lignes), mais larges (beaucoup de colonnes descriptives). Elles sont jointes à la table de faits à l’aide de clés entières de substitution.

CREATE TABLE dim_product (
  product_key  SERIAL PRIMARY KEY,
  product_name VARCHAR(200) NOT NULL,
  category     VARCHAR(100),
  brand        VARCHAR(100),
  unit_cost    NUMERIC(10, 2)
);

CREATE TABLE dim_customer (
  customer_key SERIAL PRIMARY KEY,
  full_name    VARCHAR(200) NOT NULL,
  email        VARCHAR(200),
  country      VARCHAR(100),
  segment      VARCHAR(50)
);

La dimension date

La dimension date est la dimension la plus courante dans tout entrepôt. Au lieu de stocker un TIMESTAMP brut dans la table de faits, vous stockez une clé entière qui fait référence à une table calendrier préparée à l’avance.

Les requêtes peuvent ainsi filtrer ou regrouper les données par trimestre fiscal, jour de la semaine, indicateurs de jours fériés et autres attributs du calendrier, sans effectuer de calcul sur les dates au moment de la requête.

CREATE TABLE dim_date (
  date_key       INT PRIMARY KEY,  -- e.g. 20240315
  full_date      DATE NOT NULL,
  day_of_week    VARCHAR(10),
  day_of_month   INT,
  month_num      INT,
  month_name     VARCHAR(20),
  quarter        INT,
  year           INT,
  is_holiday     BOOLEAN DEFAULT FALSE,
  fiscal_quarter INT
);

-- Sample row
INSERT INTO dim_date VALUES
  (20240315, '2024-03-15', 'Friday', 15, 3, 'March', 1, 2024, FALSE, 2);

Le modèle du schéma en étoile

Lorsque vous dessinez un diagramme avec une table de faits au centre et des tables de dimensions qui rayonnent autour d’elle, l’ensemble ressemble à une étoile — d’où le nom de schéma en étoile.

Les clés étrangères de la table de faits pointent vers les clés primaires de chaque dimension. Les requêtes joignent généralement la table de faits à une ou plusieurs dimensions afin d’ajouter un contexte descriptif aux valeurs brutes.

-- Join fact to two dimensions to enrich a sales report
SELECT
  dp.product_name,
  dp.category,
  SUM(fs.quantity)     AS total_units_sold,
  SUM(fs.total_amount) AS total_revenue
FROM fact_sales fs
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_date     dd ON dd.date_key     = fs.date_key
WHERE dd.year = 2024
GROUP BY dp.product_name, dp.category
ORDER BY total_revenue DESC;

Clés de substitution ou clés naturelles

Les tables de dimensions utilisent des clés de substitution — des entiers synthétiques générés par la base de données, indépendants de toute signification métier. Les clés naturelles (comme un SKU de produit ou l’adresse e-mail d’un client) peuvent changer au fil du temps, tandis que les clés de substitution ne changent jamais.

L’utilisation de clés de substitution isole la table de faits des modifications apportées aux systèmes en amont et accélère les jointures, car les comparaisons d’entiers sont moins coûteuses que les comparaisons de chaînes de caractères.

-- Surrogate key approach: integer join is fast
SELECT fs.sale_id, dc.full_name, fs.total_amount
FROM fact_sales fs
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dc.country = 'Germany'
LIMIT 10;

-- Natural key approach (avoid in warehouses): slower string join
-- JOIN dim_customer dc ON dc.email = fs.customer_email

Granularité : niveau de détail d’une table de faits

La granularité d’une table de faits décrit exactement ce que représente une ligne. Avant de construire un entrepôt, vous devez déclarer cette granularité — par exemple, une ligne par ligne de produit individuelle dans une commande client.

Une granularité bien définie évite les agrégations ambiguës. Si différentes lignes représentent différents événements, vos résultats SUM et COUNT n’auront aucun sens.

-- Grain: one row per product per order line
-- Each row = one line item sold in one transaction
SELECT
  sale_id,
  date_key,
  product_key,
  quantity,
  unit_price,
  total_amount
FROM fact_sales
WHERE date_key = 20240315
ORDER BY sale_id;

Mesures additives, semi-additives et non additives

Les faits appartiennent à trois catégories selon la manière dont vous pouvez les agréger :

  • Additives — peuvent être additionnées selon toutes les dimensions (par exemple, revenue et quantity).
  • Semi-additives — peuvent être additionnées selon certaines dimensions, mais pas toutes (par exemple, le balance d’un compte peut être additionné selon les clients, mais pas selon le temps).
  • Non additives — ne peuvent pas être additionnées de manière pertinente (par exemple, unit_price et ratio). Utilisez plutôt AVG ou d’autres agrégations.
SELECT
  dd.month_name,
  SUM(fs.total_amount)         AS total_revenue,   -- additive
  AVG(fs.unit_price)           AS avg_unit_price,   -- non-additive: use AVG
  SUM(fs.quantity)             AS total_units       -- additive
FROM fact_sales fs
JOIN dim_date dd ON dd.date_key = fs.date_key
WHERE dd.year = 2024
GROUP BY dd.month_name, dd.month_num
ORDER BY dd.month_num;

Dimensions à évolution lente (SCD de type 1 et 2)

Les attributs des dimensions changent au fil du temps : un client change de pays, un produit change de catégorie. Les dimensions à évolution lente (SCD) gèrent ces changements :

  • Type 1 — Remplacer l’ancienne valeur. C’est simple, mais l’historique est perdu.
  • Type 2 — Ajouter une nouvelle ligne avec une nouvelle clé de substitution et des dates de validité. Cela préserve l’intégralité de l’historique, de sorte que les faits historiques continuent de pointer vers la version correcte de la dimension.
-- SCD Type 2: add a new version of the row
ALTER TABLE dim_customer ADD COLUMN valid_from DATE;
ALTER TABLE dim_customer ADD COLUMN valid_to   DATE;
ALTER TABLE dim_customer ADD COLUMN is_current BOOLEAN DEFAULT TRUE;

-- Expire the old row
UPDATE dim_customer
SET is_current = FALSE,
    valid_to   = CURRENT_DATE - INTERVAL '1 day'
WHERE email = 'anna@example.com' AND is_current = TRUE;

-- Insert the updated version
INSERT INTO dim_customer (full_name, email, country, segment, valid_from, valid_to, is_current)
VALUES ('Anna Muller', 'anna@example.com', 'Austria', 'Premium', CURRENT_DATE, '9999-12-31', TRUE);

Dimensions dégénérées

Il arrive qu’un attribut de dimension ne nécessite pas sa propre table. Une dimension dégénérée est une clé de dimension qui réside directement dans la table de faits, sans table de dimensions correspondante.

Les numéros de commande, les numéros de facture et les identifiants de tickets en sont des exemples classiques. Ils fournissent un contexte pour explorer les données en détail, mais ne possèdent aucune autre colonne descriptive qu’il serait utile de stocker dans une table distincte.

-- order_number is a degenerate dimension:
-- it lives in the fact table, no dim_order table needed
CREATE TABLE fact_order_lines (
  line_id      SERIAL PRIMARY KEY,
  order_number VARCHAR(20) NOT NULL,  -- degenerate dimension
  date_key     INT NOT NULL,
  product_key  INT NOT NULL,
  customer_key INT NOT NULL,
  quantity     INT NOT NULL,
  line_total   NUMERIC(12, 2) NOT NULL
);

SELECT order_number, SUM(line_total) AS order_total
FROM fact_order_lines
GROUP BY order_number
ORDER BY order_total DESC
LIMIT 5;

Interroger l’intégralité du schéma en étoile

Pour tout rassembler : une requête type d’un entrepôt joint la table de faits à plusieurs dimensions, applique des filtres sur les attributs des dimensions et agrège les mesures de la table de faits.

L’optimiseur peut gérer efficacement ces jointures multiples, car les clés étrangères de la table de faits sont indexées et les tables de dimensions sont relativement petites.

SELECT
  dd.year,
  dd.quarter,
  dp.category,
  dc.country,
  SUM(fs.quantity)     AS units_sold,
  SUM(fs.total_amount) AS revenue
FROM fact_sales fs
JOIN dim_date     dd ON dd.date_key     = fs.date_key
JOIN dim_product  dp ON dp.product_key  = fs.product_key
JOIN dim_customer dc ON dc.customer_key = fs.customer_key
WHERE dd.year IN (2023, 2024)
  AND dp.category = 'Electronics'
GROUP BY dd.year, dd.quarter, dp.category, dc.country
ORDER BY dd.year, dd.quarter, revenue DESC;

Vérification rapide : faits et dimensions

Vérifiez votre compréhension des différences entre les tables de faits et les tables de dimensions dans un schéma en étoile.

Récapitulatif de la leçon

Dans cette leçon, vous avez découvert les éléments fondamentaux d’un schéma en étoile d’entrepôt de données :

  • Les tables de faits contiennent des événements mesurables (ventes, clics, transactions), avec des mesures numériques et des clés étrangères.
  • Les tables de dimensions fournissent un contexte descriptif (qui, quoi, où, quand) à l’aide de clés de substitution.
  • La granularité définit exactement ce que représente une ligne de faits : vous devez la déclarer avant la construction.
  • Les mesures sont additives, semi-additives ou non additives, ce qui détermine la manière de les agréger.
  • Les SCD de type 2 préservent les valeurs historiques des dimensions en ajoutant de nouvelles lignes avec des dates de validité.
  • Les dimensions dégénérées résident dans la table de faits lorsqu’elles ne possèdent aucun attribut supplémentaire à décrire.

Comprendre les tables de faits et les tables de dimensions constitue le fondement de la création d’entrepôts rapides, évolutifs et puissants sur le plan analytique.

Questions Fréquemment Posées

La leçon « Tables de faits et de dimensions » est-elle gratuite ?

Oui — le texte complet de « Tables de faits et de dimensions » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Tables de faits et de dimensions » ?

Les éléments fondamentaux d’un entrepôt de données. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer SQL Academy ?

Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Tables de faits et de dimensions » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?

Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. OLTP ou OLAP
  2. Tables de faits et de dimensions
  3. Schémas en étoile et en flocon
  4. Écrire des requêtes analytiques
← Retour à SQL Academy