Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Schéma Discussion :

Conception à revoir


Sujet :

Schéma

  1. #1
    Nouveau membre du Club
    Conception à revoir
    Bonsoir,

    en voulant faire une requête j'ai réalisé qu'il y avait un problème de conception.
    Voilà ce que j'ai actuellement :


    Je souhaitais faire une requête qui permette d'afficher:
    le titre d'un livre, son scénariste, le dessinateur et l'encreur


    En sachant qu'un auteur peut être un scénariste, un dessinateur, un encreur, une combinaison de 2 ou les 3 possibilités

    alors je voulais refaire mon schéma :


    mais là je suis complétement perdu

  2. #2
    Expert éminent sénior
    bonjour,

    Je suppose que le(s) scénariste(s) et le(s) dessinateur(s) sont invariants quelle que soit l'édition du livre, mais qu'en est il de l'encreur et des autres rôles ?

    Si les règles de gestion sont les suivantes
    - une même personne peut exercer plusieurs rôles (dessinateur, scénariste, coloriste...) pour un même livre
    - le rôle dépend du livre, pas de l'édition
    - un même rôle peut être exercé par plusieurs personnes pour un même livre (plusieurs auteurs, plusieurs dessinateurs...)

    Alors le MCD est le suivant :



    Ce qui donne le MLD suivant :



    Qui produit le script suivant (ici décliné pour SQL server) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    CREATE TABLE LI_livre(
       LI_ident INT IDENTITY,
       LI_titre VARCHAR(255) NOT NULL,
       PRIMARY KEY(LI_ident)
    );
    
    CREATE TABLE EO_edition(
       LI_ident INT,
       EO_ident INT IDENTITY,
       EO_ISBN CHAR(13),
       EO_resume VARCHAR(1024),
       EO_date DATE NOT NULL,
       PRIMARY KEY(LI_ident, EO_ident),
       UNIQUE(EO_ISBN),
       FOREIGN KEY(LI_ident) REFERENCES LI_livre(LI_ident)
    );
    
    CREATE TABLE IN_intervenant(
       IN_ident INT IDENTITY,
       IN_nom VARCHAR(50) NOT NULL,
       IN_prenom VARCHAR(50) NOT NULL,
       IN_pseudo VARCHAR(5),
       IN_ddn DATE NOT NULL,
       PRIMARY KEY(IN_ident)
    );
    
    CREATE TABLE RL_role(
       RL_ident INT IDENTITY,
       RL_code CHAR(4) NOT NULL,
       RL_libelle VARCHAR(128) NOT NULL,
       PRIMARY KEY(RL_ident),
       UNIQUE(RL_code)
    );
    
    CREATE TABLE EX_exemplaire(
       LI_ident INT,
       EO_ident INT,
       EX_ident INT IDENTITY,
       EX_codbar CHAR(12) NOT NULL,
       EX_datimp DATE NOT NULL,
       PRIMARY KEY(LI_ident, EO_ident, EX_ident),
       UNIQUE(EX_codbar),
       FOREIGN KEY(LI_ident, EO_ident) REFERENCES EO_edition(LI_ident, EO_ident)
    );
    
    CREATE TABLE IR_intervenir(
       LI_ident INT,
       IN_ident INT,
       RL_ident INT,
       PRIMARY KEY(LI_ident, IN_ident, RL_ident),
       FOREIGN KEY(LI_ident) REFERENCES LI_livre(LI_ident),
       FOREIGN KEY(IN_ident) REFERENCES IN_intervenant(IN_ident),
       FOREIGN KEY(RL_ident) REFERENCES RL_role(RL_ident)
    );

    EDIT : tout livre n'est pas publié, il faut donc corriger la cardinalité mini pour la remplacer par zéro de [LI_livre] vers (publier)

  3. #3
    Nouveau membre du Club
    Requête SQL
    Hum, c'est intéressant et tes tables livre, intervenant, intervenir, role sont très proche que ce que j'avais ... j'étais proche de la bonne direction.

    Avec un ensemble comme celui que tu proposes.

    J'avais fait ça pour afficher : nom du livre, nom du scenariste, nom du dessinateur, nom de l'encreur avec mon ensemble d'origine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT 
        livre_titre,
        A1.auteur_nom,
        A2.auteur_nom,
        A3.auteur_nom
    FROM 
        livre AS L
    INNER JOIN auteur AS A1
        ON A1.auteur_id = L.livre_scenariste
    INNER JOIN auteur AS A2
        ON A2.auteur_id = L.livre_dessinateur
    INNER JOIN auteur AS A3
        ON A3.auteur_id = L.livre_encreur;
    Une telle requête fonctionne toujours ou il faut rajouter les tables de liaisons ?

  4. #4
    Expert éminent sénior
    Une telle requête ne fonctionne plus.
    Cette requête s'appuie sur un modèle non évolutif : la table LIVRE contient 3 FK, une par type d'intervenant (auteur, dessinateur, encreur)
    Or un livre peut avoir plusieurs auteurs, c'est très courant, exemple que je cite souvent "paris brûle-t-il" de Dominique Lapierre et Larry Collins
    Un livre peut ne pas avoir de dessinateur, pas d'encreur, autant de cas où votre modèle comportera des marqueurs "null"
    Un livre peut avoir plein d'autres intervenants (auteur de la préface, éditeur, imprimeur, coloriste...), qui ne vous intéressent peut être pas aujourd'hui mais qui nécessiteront des modifications dans vos tables s'ils vous intéressent demain.
    Alors que le modèle que je propose permet d'ajouter autant d'intervenants que nécessaire, sans besoin de modifier la structure des tables, et sans nécessité de gérer les marqueurs "null".

    Il faut donc bien évidemment utiliser la table associative IR_intervenir de mon modèle pour faire le lien entre une personne, un rôle, et un livre.

  5. #5
    Nouveau membre du Club
    C'est bien ce que je pensais ... oulà ça commence à être très compliqué.
    Quelque chose de ce genre fonctionnerait ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT 
        LI.LI_nom,
        RL.RL_nom,
        IN.IN_nom
    FROM 
        IR_intervenir AS IR
    INNER JOIN RL_role as RL
        ON IR.RL_iden = RL.RL_iden 
    INNER JOIN IN_intervant AS IN
        ON IR.IN_iden = IN.IN_iden 
    INNER JOIN LI_livre AS LI
        ON IR.LI_iden = LI.LI_iden 
    ;
    ON IR.RL_iden = RL.RL_iden permet de faire le lien avec le role
    ON IR.IN_iden = IN.IN_iden permet de faire le lien avec la personne
    ON IR.LI_iden = LI.LI_iden permet de faire le lien avec le livre

  6. #6
    Expert éminent sénior
    C'est le principe, à part que la table rôle et la table livre n'ont pas de colonne "nom"

    Voici deux exemples (j'ai pu faire des fautes de frappe, je ne les ai pas exécutées) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    -- Faire la liste des livres dans lesquels Dominique Lapierre ou Larry Collins interviennent et récupérer leur rôle
       select IN.IN_nom      as nom
            , IN.IN_prenom   as prenom
            , RL.RL_libelle  as role
            , LI.LI_titre    as titre
       from IN_intervenant as IN
       inner join IR_intervenir  as IR
          on IR.IN_ident = IN.IN_ident
       inner join LI_livre  as LI
          on LI.LI_ident=IR.LI_ident
       inner join RL_role  as RL
          on RL.RL_ident = IR.IR_ident
       where (IN.IN_nom='Lapierre' and IN.IN_prenom = 'Dominique'
          or (IN.IN_nom='Collins'  and IN.IN_prenom = 'Larry')    
       order by IN.IN_nom     
              , IN.IN_prenom  
              , LI.LI_titre  
    
    -- faire la liste des intervenants du livre "Paris brûle-t-il"
       select LI.LI_titre    as titre
            , IN.IN_nom      as nom
            , IN.IN_prenom   as prenom
            , RL.RL_libelle  as role
       from LI_livre as LI
       inner join IR_intervenir  as IR
          on IR.LI_ident = LI.LI_ident
       inner join IN_intervenant as IN
          on IN.IN_ident = IR.IN_ident
       inner join RL_role  as RL
          on RL.RL_ident = IR.IR_ident
       where LI.LI_titre = 'Paris brûle-t-il'

  7. #7
    Nouveau membre du Club
    Oui effectivement ... mais c'était plus pour voir si j'avais compris l'idée.


###raw>template_hook.ano_emploi###