B03 - Traduire un héritage UML en tables : TPH, TPT, TPC

Objectif

Une base relationnelle ne connaît pas l’héritage (« un Meuble est un Produit »). Savoir choisir et coder les 3 stratégies. Corrigé détaillé du cours : Exercice Héritage - Produits et Véhicules.


1. Le cas d’étude

classDiagram
    class Produit {
        <<abstract>>
        +String reference
        +String designation
        +Decimal prixVente
        +int stock
    }
    class Meuble {
        +int hauteur
        +int largeur
        +int profondeur
    }
    class Kit {
        +String urlNotice
    }
    class Equipement {
        +String categorie
    }
    Produit <|-- Meuble
    Produit <|-- Kit
    Produit <|-- Equipement

2. Les trois stratégies

flowchart LR
  subgraph TPH["TPH : 1 table"]
    T1["PRODUITS<br/>reference PK<br/>designation, prix, stock<br/>type_produit (discriminant)<br/>hauteur NULL, url_notice NULL,<br/>categorie NULL…"]
  end
  subgraph TPT["TPT : 1 table mère + 1 par fille"]
    M["PRODUITS (commun)"] --- F1["MEUBLES<br/>reference PK+FK"]
    M --- F2["KITS<br/>reference PK+FK"]
    M --- F3["EQUIPEMENTS<br/>reference PK+FK"]
  end
  subgraph TPC["TPC : 1 table par classe concrète"]
    C1["MEUBLES<br/>(tous les champs)"]
    C2["KITS<br/>(tous les champs)"]
    C3["EQUIPEMENTS<br/>(tous les champs)"]
  end

TPH - Table Per Hierarchy (choix de l’exercice)

CREATE TABLE Produits (
    reference    VARCHAR(50)   PRIMARY KEY,
    designation  NVARCHAR(200) NOT NULL,
    prix_vente   DECIMAL(10,2) NOT NULL CHECK (prix_vente >= 0),
    stock        INT           NOT NULL DEFAULT 0,
    type_produit VARCHAR(20)   NOT NULL
        CONSTRAINT CK_Produit_Type CHECK (type_produit IN ('MEUBLE', 'KIT', 'EQUIPEMENT')),
    id_finition  INT NULL REFERENCES Finitions(id_finition),
    hauteur_cm   INT NULL,
    url_notice   NVARCHAR(500) NULL,
    -- Règle métier : finition obligatoire pour meubles et kits, interdite pour les équipements
    CONSTRAINT CK_Finition CHECK (
        (type_produit = 'EQUIPEMENT' AND id_finition IS NULL) OR
        (type_produit <> 'EQUIPEMENT' AND id_finition IS NOT NULL))
);
SELECT * FROM Produits WHERE type_produit = 'KIT';   -- aucune jointure

TPT - Table Per Type

CREATE TABLE Produits (
    reference   VARCHAR(50) PRIMARY KEY,
    designation NVARCHAR(200) NOT NULL,
    prix_vente  DECIMAL(10,2) NOT NULL,
    stock       INT NOT NULL DEFAULT 0
);
CREATE TABLE Meubles (
    reference   VARCHAR(50) PRIMARY KEY REFERENCES Produits(reference),  -- PK = FK
    id_finition INT NOT NULL REFERENCES Finitions(id_finition),
    hauteur_cm  INT NOT NULL
);
CREATE TABLE Kits (
    reference   VARCHAR(50) PRIMARY KEY REFERENCES Produits(reference),
    id_finition INT NOT NULL REFERENCES Finitions(id_finition),
    url_notice  NVARCHAR(500) NOT NULL
);
-- La composition ne peut lier QUE des kits à des meubles : garanti par les FK
CREATE TABLE Kit_Meuble (
    ref_kit    VARCHAR(50) REFERENCES Kits(reference),
    ref_meuble VARCHAR(50) REFERENCES Meubles(reference),
    quantite   INT NOT NULL CHECK (quantite > 0),
    PRIMARY KEY (ref_kit, ref_meuble)
);
-- Insérer un meuble = 2 INSERT dans une transaction
BEGIN TRANSACTION;
INSERT INTO Produits VALUES ('MEU-001', N'Banquette', 349.00, 5);
INSERT INTO Meubles VALUES ('MEU-001', 1, 45);
COMMIT;

TPC - Table Per Concrete class

Pas de table mère : chaque table répète les colonnes communes. Simple, mais une ligne de commande ne peut plus pointer vers « un produit quelconque » avec une seule clé étrangère → rarement adapté.

3. Comparatif

CritèreTPHTPTTPC
Nombre de tables11 + nn
Colonne discriminanteOuiNonNon
Colonnes NULLBeaucoupAucune artificielleAucune
NOT NULL sur les attributs spécifiquesVia CHECK conditionnelsNatifNatif
Lecture⚡ Rapide (0 jointure)JointuresRapide par type, UNION pour tout lister
Écriture1 INSERT2 INSERT (transaction)1 INSERT
FK vers « un produit quelconque »✅✅❌
FK vers « un meuble uniquement »❌ (trigger)✅✅
Quand l’utiliserPeu d’attributs spécifiques, lecture intensive (e-commerce)Beaucoup d’attributs spécifiques obligatoires, intégrité stricteSous-types totalement indépendants

Voir aussi