Zéro Faute

[40 min]

L'entreprise ZéroDéfo veut répertorier ses fautes de production. Une faute est définie dans le manuel qualité de l'entreprise comme « un défaut constaté sur une pièce produite en fin de chaîne ». L'entreprise veut associer les fautes aux produits concernés. Chaque faute est classifiée dans des catégories et sous-catégories. Chaque produit est basé sur un modèle.

  • Pour chaque modèle, on veut gérer son code constitué de 8 caractères alphanumériques, son nom et la date de mise sur le marché.

  • Pour chaque produit, on veut connaître le modèle associé, le numéro de série (6 chiffres) et le numéro de produit (max. 4 caractères) ainsi que l'année de production. Un produit est identifié par son numéro de série et son numéro de produit.

    Plusieurs produits partagent le même numéro de série (tous les produits de cette série), et deux produits peuvent avoir (par hasard) le même numéro de produit, dans des séries différentes (qui ont adopté le même système de codage des produits).

  • Une faute concerne toujours un produit. Elle possède un code unique, un titre et la date de détection. Elle peut éventuellement avoir un commentaire et la date de réparation si le produit a été réparé.

  • Les fautes sont classifiées dans des sous-catégories et chaque sous-catégorie fait partie d'une catégorie. Une faute est toujours classifiée dans une sous-catégorie au moins (elle peut être classifiée dans plusieurs).

  • Les catégories et les sous-catégories possèdent un nom et, optionnellement, une description.

Question

Proposez un diagramme UML répondant aux besoins de cette entreprise.

Question

Proposez un modèle relationnel en 3NF basé sur votre modèle UML. Justifiez les choix que vous faites (transformation des héritages, associations 1-1...).

Solution

MLD
1
Modèle(#code : chaîne, nom : chaîne, dateMiseSurMarché : date)
2
     avec dateMiseSurMarché non-null
3
4
Produit(#numSérie : entier, #numProduit : chaîne, annéeProduction : entier, modèle=>Modèle)
5
     avec annéeProduction non-nul
6
     avec modèle non-nul
7
8
SurCatégorie(#nom : chaîne, description : chaîne)
9
SousCatégorie(#nom : chaîne, description : chaîne, surCatégorie=>SurCatégorie)
10
     avec surCatégorie non-null
11
     avec PROJ(SurCatégorie, nom) = PROJ(SousCatégorie, surCatégorie)
12
     avec PROJ(SousCatégorie, nom) INTER PROJ(SurCatégorie, nom) = {}
13
14
Faute(#code : chaîne, titre : chaîne, dateDétection : date, dateRéparation : date, commentaire : chaîne, produitSérie=>Produit(numSérie), produitNuméro=>Produit(numProduit))
15
     avec titre non-nul
16
     avec dateDétection non-nul
17
     avec produitSérie non-nul
18
     avec produitNuméro non-nul
19
20
ClassementFaute(#faute=>Faute(code), #sousCatégorie=>SousCatégorie(nom))
21
    PROJ(Faute, code) = PROJ(ClassementFaute, faute)
Justification de la 3NF
  1. 1NF : toutes les relations ont une clé et chaque attribut est atomique.

  2. 2NF :

    • Modèle, SurCatégorie, SousCatégorie et Faute ont des clés constituées d'un seul attribut ;

    • ClassementFaute ne comporte pas d'attribut en dehors de la clé ;

    • dans Produit, il n'existe pas de dépendance fonctionnelle de numSérie vers annéeProduction ou modèle, ou les deux, idem pour numProduit.

  3. 3NF : dans les relations Modèle, Produit et Faute, il n'existe pas de dépendance fonctionnelle entre attributs ou groupe d'attributs en dehors de la clé.

Question

Écrivez le code SQL LDD permettant de créer la base de données correspondant au modèle relationnel.

Solution

1
CREATE TABLE tModele
2
(
3
    code CHAR(8) PRIMARY KEY,
4
    nom VARCHAR NOT NULL,
5
    dateMiseSurMarche DATE NOT NULL
6
);
7
CREATE TABLE tProduit
8
(
9
    numSerie NUMERIC(6) NOT NULL,
10
    numProduit VARCHAR(4) NOT NULL,
11
    anneeProduction INTEGER NOT NULL,
12
    modele CHAR(8) NOT NULL,
13
    PRIMARY KEY (numSerie, numProduit),
14
    FOREIGN KEY (modele) REFERENCES tModele(code)
15
);    
16
CREATE TABLE tSurCategorie
17
(
18
    nom VARCHAR PRIMARY KEY,
19
    description VARCHAR
20
);
21
CREATE TABLE tSousCategorie
22
(
23
    nom VARCHAR PRIMARY KEY,
24
    description VARCHAR,
25
    surCategorie VARCHAR,
26
    FOREIGN KEY (surCategorie) REFERENCES tSurCategorie(nom)
27
);
28
CREATE TABLE tFaute
29
(
30
    code VARCHAR PRIMARY KEY,
31
    titre VARCHAR NOT NULL,
32
    dateDetection DATE NOT NULL,
33
    dateReparation DATE,
34
    commentaire VARCHAR,
35
    produitSerie NUMERIC(6) NOT NULL,
36
    produitNumero VARCHAR(4) NOT NULL,
37
    FOREIGN KEY (produitSerie, produitNumero) REFERENCES tProduit(numSerie, numProduit)
38
);
39
CREATE TABLE tClassementFaute
40
(
41
    faute VARCHAR NOT NULL,
42
    sousCategorie VARCHAR NOT NULL,
43
    PRIMARY KEY (faute, sousCategorie),
44
    FOREIGN KEY (faute) REFERENCES tFaute(code),
45
    FOREIGN KEY (sousCategorie) REFERENCES tSouscategorie(nom)
46
);

Question

Écrivez une requête SQL permettant de lister le nombre de fautes par nom de modèle et par numéro de série.

Solution

1
SELECT m.nom, p.numSerie, COUNT(*)
2
FROM tModele m, tProduit p, tFaute f
3
WHERE m.code = p.modele
4
    AND p.numSerie = f.produitSerie
5
    AND p.numProduit = f.produitNumero
6
GROUP BY m.nom, p.numSerie
7
;
1
SELECT m.nom, p.numeroSerie, COUNT(*)
2
FROM (tModele m
3
    JOIN tProduit p
4
        ON m.code = p.modele)
5
    JOIN tFaute f
6
        ON (p.numSerie = f.produitSerie AND p.numProduit = f.produitNumero)
7
GROUP BY m.nom, p.numSerie
8
;
Attention

Bien que le numéro de produit ne participe pas à la projection (SELECT) ni au regroupement (GROUP BY), il ne faut pas oublier la jointure entre tProduit.numProduit et tFaute.produitNumero.