IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Inventaire livres bibliothèque personnelle


Sujet :

Schéma

  1. #61
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonjour almoa,

    Citation Envoyé par almoa
    Supposons par exemple que j’enregistre dans mon application une édition originale (e1) d’une œuvre française en grand format (GF). J’enregistre ses caractéristiques propres. Potentiellement une édition étrangère (e2) de cette œuvre (traduite du français vers une autre langue) peut exister (GF ou poche). De même potentiellement il peut exister une édition française de la même œuvre en poche (e3) ou alors en GF (e4) mais d’un autre éditeur. Il est alors important de distinguer deux cas de figure :

    a) Je possède une édition liée (e2 ou e3 ou e4) à e1 (1 % des cas) : cette édition doit être enregistrée avec toutes ses caractéristiques propres (titre, éditeur, année parution, contributeur…), comme c’est le cas de toutes les éditions possédées. A l’affichage dans l’application, il devra m’être signalé qu’il existe une édition liée possédée que je peux afficher à son tour.

    b) Je ne possède pas l’édition liée (e2 ou e3 ou e4) à e1 (99 % des cas) : lors de l’enregistrement de l’édition que je possède, il s’agit seulement de faire référence à l’édition liée (e2 ou e3 ou e4) en notant son titre (si différent : titre VO), éditeur et année de parution. Je trouve ces références dans l’édition possédée généralement dans la page mentionnant le copyright. A l’affichage de l’édition possédée, il sera fait mention desdites références.
    Cas (a) il faudrait donc créer e2, e3, e4 en tant qu’éditions non possédées et établir un lien entre e1 et ces éditions ;

    Cas (b) il faut donc créer e2, e3, e4 en tant qu’éditions possédées et établir un lien entre e1 et ces éditions.

    Ci-joint une vue d’une partie d’un MCD en cours d’élaboration. A vous de préciser ce qui ne va pas...

    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  2. #62
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonjour fsmrel,

    J'ai essayé de construire dans Looping la partie du MCD proposé. Le MLD généré est le suivant :

    Nom : 2024-12-21 15_23_03-Looping - [Biblio-Dec-2024.loo].png
Affichages : 162
Taille : 42,0 Ko

    et le script SQL est le suivant :

    Code SQL : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    CREATE TABLE Ouvrage(
       OuvrageId SERIAL,
       OuvrageTitre VARCHAR(100)  NOT NULL,
       PRIMARY KEY(OuvrageId)
    );
     
    CREATE TABLE Editeur(
       EditeurId SERIAL,
       EditeurNom VARCHAR(100) ,
       PRIMARY KEY(EditeurId)
    );
     
    CREATE TABLE EditionType(
       EditionTypeId SERIAL,
       EditionTypeLibelle VARCHAR(100) ,
       PRIMARY KEY(EditionTypeId)
    );
     
    CREATE TABLE Format(
       FormatId SERIAL,
       FormatLibelle VARCHAR(100) ,
       PRIMARY KEY(FormatId)
    );
     
    CREATE TABLE Contributeur(
       ContributeurId SERIAL,
       ContributeurNom VARCHAR(100) ,
       PRIMARY KEY(ContributeurId)
    );
     
    CREATE TABLE ContributionType(
       ContributionTypeId SERIAL,
       ContributionTypeLibelle VARCHAR(100) ,
       PRIMARY KEY(ContributionTypeId)
    );
     
    CREATE TABLE Edition(
       OuvrageId INTEGER,
       EditionNumero SERIAL,
       AnneParution DATE,
       EditeurId INTEGER NOT NULL,
       PRIMARY KEY(OuvrageId, EditionNumero),
       FOREIGN KEY(OuvrageId) REFERENCES Ouvrage(OuvrageId),
       FOREIGN KEY(EditeurId) REFERENCES Editeur(EditeurId)
    );
     
    CREATE TABLE EditionNonPossedee(
       Id_EditionNonPossedee SERIAL,
       OuvrageId INTEGER NOT NULL,
       EditionNumero INTEGER NOT NULL,
       PRIMARY KEY(Id_EditionNonPossedee),
       UNIQUE(EditionNumero),
       FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES Edition(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE EditionPossedee(
       Id_EditionPossedee SERIAL,
       ISBN13 VARCHAR(13) ,
       EditionDateAchat DATE,
       FormatId INTEGER NOT NULL,
       OuvrageId INTEGER NOT NULL,
       EditionNumero INTEGER NOT NULL,
       PRIMARY KEY(Id_EditionPossedee),
       UNIQUE(EditionNumero),
       FOREIGN KEY(FormatId) REFERENCES Format(FormatId),
       FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES Edition(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE EdiEnfantFrancais(
       Id_EdiEnfantFrancais SERIAL,
       Id_EditionPossedee_SourceGrandFormatFrançais INTEGER NOT NULL,
       Id_EditionPossedee_EnfantDeParentFrançais INTEGER NOT NULL,
       PRIMARY KEY(Id_EdiEnfantFrancais),
       UNIQUE(Id_EditionPossedee_SourceGrandFormatFrançais),
       UNIQUE(Id_EditionPossedee_EnfantDeParentFrançais),
       FOREIGN KEY(Id_EditionPossedee_SourceGrandFormatFrançais) REFERENCES EditionPossedee(Id_EditionPossedee),
       FOREIGN KEY(Id_EditionPossedee_EnfantDeParentFrançais) REFERENCES EditionPossedee(Id_EditionPossedee)
    );
     
    CREATE TABLE EdiEnfantDeParentEtranger(
       Id_EdiEnfantDeParentEtranger SERIAL,
       Id_EditionPossedee_EnfantDeParentPasEnFrançais INTEGER NOT NULL,
       PRIMARY KEY(Id_EdiEnfantDeParentEtranger),
       UNIQUE(Id_EditionPossedee_EnfantDeParentPasEnFrançais),
       FOREIGN KEY(Id_EditionPossedee_EnfantDeParentPasEnFrançais) REFERENCES EditionPossedee(Id_EditionPossedee)
    );
     
    CREATE TABLE Referencer(
       Id_EditionPossedee INTEGER,
       Id_EditionNonPossedee INTEGER,
       PRIMARY KEY(Id_EditionPossedee, Id_EditionNonPossedee),
       FOREIGN KEY(Id_EditionPossedee) REFERENCES EditionPossedee(Id_EditionPossedee),
       FOREIGN KEY(Id_EditionNonPossedee) REFERENCES EditionNonPossedee(Id_EditionNonPossedee)
    );
     
    CREATE TABLE Edi_Type(
       Id_EditionPossedee INTEGER,
       EditeurId INTEGER,
       EditionTypeId INTEGER,
       AnneeParution DATE,
       PRIMARY KEY(Id_EditionPossedee, EditeurId, EditionTypeId),
       FOREIGN KEY(Id_EditionPossedee) REFERENCES EditionPossedee(Id_EditionPossedee),
       FOREIGN KEY(EditeurId) REFERENCES Editeur(EditeurId),
       FOREIGN KEY(EditionTypeId) REFERENCES EditionType(EditionTypeId)
    );
     
    CREATE TABLE Edi_Con(
       Id_EditionPossedee INTEGER,
       ContributeurId INTEGER,
       ContributionTypeId INTEGER,
       PRIMARY KEY(Id_EditionPossedee, ContributeurId, ContributionTypeId),
       FOREIGN KEY(Id_EditionPossedee) REFERENCES EditionPossedee(Id_EditionPossedee),
       FOREIGN KEY(ContributeurId) REFERENCES Contributeur(ContributeurId),
       FOREIGN KEY(ContributionTypeId) REFERENCES ContributionType(ContributionTypeId)
    );

    J'ai peut-être fait des erreurs dans la transcription du MCD :

    - La contrainte d'unicité porte sur "EditionNumero". Ne devrait-elle pas plutôt porter sur le couple (OuvrageId, EditionNumero) qui est déjà la clé primaire de la table [Edition] ?

    - J'ai du mal à comprendre la conception des tables [EdiEnfantFrancais] et [EdiEnfantDeParentEtranger]. Je voyais plus une colonne "Id_EditionPossedee_Parent" dans la table EditionPossedee (mais problème elle pourrait être NULL...)

    - La présence de "AnneeParution" dans la table [Edi_Type] ne serait-elle pas redondante car déjà présente dans la table [Edition] ?

    Par ailleurs, je ne suis pas sûr de saisir ce que recoupe la notion de "types d'édition" dans la table [EditionType].

    Merci par avance de votre éclairage.

  3. #63
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonjour almoha,

    Votre MLD diffère quelque peu du mien, lequel est le suivant, obtenu à partir de mon dernier MCD :  
     
     
    Au stade MCD, Les entités-types EditionPossedee et EditionNonPossedee sont des spécialisations de l’entité-type Edition, en conséquence de quoi elles héritent de l’identifiant de celle-ci {OuvrageId, EditionNumero}.
     
    Ceci vaut au stade du MLD : les tables EditionPossedee et EditionNonPossedee ont pour clé primaire la paire {OuvrageId, EditionNumero}, qui est aussi clé étrangère en relation avec la table Edition.  
     
    Les attributs Id_EditionPossedee et Id_EditionNonPossedee que vous utilisez pour les tables EditionPossedee et EditionNonPossedee n’ont pas lieu d’être et doivent disparaître. En créant votre propre MCD, vous avez sans doute pensé généralisation et non pas spécialisation : il serait opportun que vous le présentiez.
     
    Le code SQL issu de mon MLD :
     
    Code SQL : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    CREATE TABLE Editeur(
       EditeurId SMALLINT,
       EditeurNom SMALLINT NOT NULL,
       CONSTRAINT Editeur_PK PRIMARY KEY(EditeurId),
       CONSTRAINT Editeur_AK UNIQUE(EditeurNom)
    );
     
    CREATE TABLE Format(
       FormatId SMALLINT,
       FormatLibelle VARCHAR(50) NOT NULL,
       CONSTRAINT Format_PK PRIMARY KEY(FormatId),
       CONSTRAINT Format_AK UNIQUE(FormatLibelle)
    );
     
    CREATE TABLE Contributeur(
       ContributeurId SMALLINT,
       ContributeurNom VARCHAR(50) NOT NULL,
       CONSTRAINT Contributeur_PK PRIMARY KEY(ContributeurId),
       CONSTRAINT Contributeur_AK UNIQUE(ContributeurNom)
    );
     
    CREATE TABLE EditionType(
       EditionTypeId SMALLINT,
       EditionTypeLibelle VARCHAR(50) NOT NULL,
       CONSTRAINT EditionType_PK PRIMARY KEY(EditionTypeId),
       CONSTRAINT EditionType_AK UNIQUE(EditionTypeLibelle)
    );
     
    CREATE TABLE ContributionType(
       ContributionTypeId SMALLINT,
       ContributionTypeLibelle VARCHAR(50) NOT NULL,
       CONSTRAINT ContributionType_PK PRIMARY KEY(ContributionTypeId),
       CONSTRAINT ContributionType_AK UNIQUE(ContributionTypeLibelle)
    );
     
    CREATE TABLE Ouvrage(
       OuvrageId SMALLINT,
       OuvrageTitre VARCHAR(50) NOT NULL,
       CONSTRAINT Ouvrage_PK PRIMARY KEY(OuvrageId)
    );
     
    CREATE TABLE Edition(
       OuvrageId SMALLINT,
       EditionNumero INT,
       EditeurId SMALLINT NOT NULL,
       CONSTRAINT Edition_PK PRIMARY KEY(OuvrageId, EditionNumero),
       CONSTRAINT Edition_Ouvrage_FK FOREIGN KEY(OuvrageId) REFERENCES Ouvrage(OuvrageId),
       CONSTRAINT Edition_Editeur_FK FOREIGN KEY(EditeurId) REFERENCES Editeur(EditeurId)
    );
     
    CREATE TABLE EditionPossedee(
       OuvrageId SMALLINT,
       EditionNumero INT,
       ISBN13 VARCHAR(13) NOT NULL,
       EditionDateAchat DATE NOT NULL,
       FormatId SMALLINT NOT NULL,
       CONSTRAINT EditionPossedee_PK PRIMARY KEY(OuvrageId, EditionNumero),
       CONSTRAINT EditionPossedee_AK UNIQUE(ISBN13),
       CONSTRAINT EditionPossedee_Edition_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES Edition(OuvrageId, EditionNumero),
       CONSTRAINT EditionPossedee_Format_FK FOREIGN KEY(FormatId) REFERENCES Format(FormatId)
    );
     
    CREATE TABLE EditionNonPossedee(
       OuvrageId SMALLINT,
       EditionNumero INT,
       CONSTRAINT EditionNonPossedee_PK PRIMARY KEY(OuvrageId, EditionNumero),
       CONSTRAINT EditionNonPossedee_Edition_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES Edition(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE EdiEnfantDeParentEtranger(
       OuvrageId_EnfantDeParentPasEnFrançais SMALLINT,
       EditionNumero_EnfantDeParentPasEnFrançais INT,
       CONSTRAINT EdiEnfantDeParentEtranger_PK PRIMARY KEY(OuvrageId_EnfantDeParentPasEnFrançais, EditionNumero_EnfantDeParentPasEnFrançais),
       CONSTRAINT EdiEnfantDeParentEtranger_EditionPossedee_EnfantDeParentPasEnFrançais_FK FOREIGN KEY(OuvrageId_EnfantDeParentPasEnFrançais, EditionNumero_EnfantDeParentPasEnFrançais) REFERENCES EditionPossedee(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE EdiEnfantFrançais(
       OuvrageId_EnfantDeParentFrançais SMALLINT,
       EditionNumero_EnfantDeParentFrançais INT,
       OuvrageId_SourceGrandFormatFrançais SMALLINT NOT NULL,
       EditionNumero_SourceGrandFormatFrançais INT NOT NULL,
       CONSTRAINT EdiEnfantFrançais_PK PRIMARY KEY(OuvrageId_EnfantDeParentFrançais, EditionNumero_EnfantDeParentFrançais),
       CONSTRAINT EdiEnfantFrançais_AK UNIQUE(OuvrageId_SourceGrandFormatFrançais, EditionNumero_SourceGrandFormatFrançais),
       CONSTRAINT EdiEnfantFrançais_EditionPossedee_EnfantDeParentFrançais_FK FOREIGN KEY(OuvrageId_EnfantDeParentFrançais, EditionNumero_EnfantDeParentFrançais) REFERENCES EditionPossedee(OuvrageId, EditionNumero),
       CONSTRAINT EdiEnfantFrançais_EditionPossedee_SourceGrandFormatFrançais_FK FOREIGN KEY(OuvrageId_SourceGrandFormatFrançais, EditionNumero_SourceGrandFormatFrançais) REFERENCES EditionPossedee(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE Edi_Con(
       OuvrageId SMALLINT,
       EditionNumero INT,
       ContributeurId SMALLINT,
       ContributionTypeId SMALLINT,
       CONSTRAINT Edi_Con_PK PRIMARY KEY(OuvrageId, EditionNumero, ContributeurId, ContributionTypeId),
       CONSTRAINT Edi_Con_EditionPossedee_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES EditionPossedee(OuvrageId, EditionNumero),
       CONSTRAINT Edi_Con_Contributeur_FK FOREIGN KEY(ContributeurId) REFERENCES Contributeur(ContributeurId),
       CONSTRAINT Edi_Con_ContributionType_FK FOREIGN KEY(ContributionTypeId) REFERENCES ContributionType(ContributionTypeId)
    );
     
    CREATE TABLE Edi_Type(
       OuvrageId SMALLINT,
       EditionNumero INT,
       EditeurId SMALLINT,
       EditionTypeId SMALLINT,
       AnneeParution INT NOT NULL,
       CONSTRAINT Edi_Type_PK PRIMARY KEY(OuvrageId, EditionNumero, EditeurId, EditionTypeId),
       CONSTRAINT Edi_Type_EditionPossedee_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES EditionPossedee(OuvrageId, EditionNumero),
       CONSTRAINT Edi_Type_Editeur_FK FOREIGN KEY(EditeurId) REFERENCES Editeur(EditeurId),
       CONSTRAINT Edi_Type_EditionType_FK FOREIGN KEY(EditionTypeId) REFERENCES EditionType(EditionTypeId)
    );
     
    CREATE TABLE Referencer(
       OuvrageId SMALLINT,
       EditionNumero INT,
       OuvrageId_1 SMALLINT,
       EditionNumero_1 INT,
       CONSTRAINT Referencer_PK PRIMARY KEY(OuvrageId, EditionNumero, OuvrageId_1, EditionNumero_1),
       CONSTRAINT Referencer_EditionPossedee_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES EditionPossedee(OuvrageId, EditionNumero),
       CONSTRAINT Referencer_EditionNonPossedee_1_FK FOREIGN KEY(OuvrageId_1, EditionNumero_1) REFERENCES EditionNonPossedee(OuvrageId, EditionNumero)
    );
     
     
    Histoire d’éviter d’avoir des noms d’attributs à rallonge, tels que OuvrageId_EnfantDeParentFrançais, EditionNumero_EnfantDeParentFrançais, etc., une fois que vous en avez noté la sémantique vous pouvez raccourcir les suffixes, comme je l’ai fait ci-dessous (voire carrément les supprimer) :
     
     
    Code SQL correspondant :
     
    Code SQL : 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
    CREATE TABLE EditionPossedee(
       OuvrageId SMALLINT,
       EditionNumero INT,
       ISBN13 VARCHAR(13) NOT NULL,
       EditionDateAchat DATE NOT NULL,
       FormatId SMALLINT NOT NULL,
       CONSTRAINT EditionPossedee_PK PRIMARY KEY(OuvrageId, EditionNumero),
       CONSTRAINT EditionPossedee_AK UNIQUE(ISBN13),
       CONSTRAINT EditionPossedee_Edition_FK FOREIGN KEY(OuvrageId, EditionNumero) REFERENCES Edition(OuvrageId, EditionNumero),
       CONSTRAINT EditionPossedee_Format_FK FOREIGN KEY(FormatId) REFERENCES Format(FormatId)
    );
     
    CREATE TABLE EdiEnfantFrançais(
       OuvrageId_EPF SMALLINT,
       EditionNumero_EPF INT,
       OuvrageId_SGFF SMALLINT NOT NULL,
       EditionNumero_SGFF INT NOT NULL,
       CONSTRAINT EdiEnfantFrançais_PK PRIMARY KEY(OuvrageId_EPF, EditionNumero_EPF),
       CONSTRAINT EdiEnfantFrançais_AK UNIQUE(OuvrageId_SGFF, EditionNumero_SGFF),
       CONSTRAINT EdiEnfantFrançais_EditionPossedee_EPF_FK FOREIGN KEY(OuvrageId_EPF, EditionNumero_EPF) REFERENCES EditionPossedee(OuvrageId, EditionNumero),
       CONSTRAINT EdiEnfantFrançais_EditionPossedee_SGFF_FK FOREIGN KEY(OuvrageId_SGFF, EditionNumero_SGFF) REFERENCES EditionPossedee(OuvrageId, EditionNumero)
    );
     
    CREATE TABLE EdiEnfantDeParentEtranger(
       OuvrageId_EPNF SMALLINT,
       EditionNumero_EPNF INT,
       CONSTRAINT EdiEnfantDeParentEtranger_PK PRIMARY KEY(OuvrageId_EPNF, EditionNumero_EPNF),
       CONSTRAINT EdiEnfantDeParentEtranger_EditionPossedee_EPNF_FK FOREIGN KEY(OuvrageId_EPNF, EditionNumero_EPNF) REFERENCES EditionPossedee(OuvrageId, EditionNumero)
    );
     
    Citation Envoyé par almoha
    J'ai du mal à comprendre la conception des tables [EdiEnfantFrancais] et [EdiEnfantDeParentEtranger]. Je voyais plus une colonne "Id_EditionPossedee_Parent" dans la table EditionPossedee (mais problème elle pourrait être NULL...)
     
    En fait, le MCD que j’ai proposé n’est qu’une vue d’un MCD plus vaste. Par exemple, l’entité-type EdiEnfantDeParentEtranger pourrait faire l’objet à son tour d’une spécialisation en entités-types EdiEnfantDeParentEtrangerTraduit et EdiEnfantDeParentEtrangerPasTraduit ; elle pourrait être à l’origine d’une association avec EditionPossedee (parenté pas en français) : ces possibilités sont liées aux réponses aux questions que j’ai posées.
     
    Citation Envoyé par almoha
    Je voyais plus une colonne "Id_EditionPossedee_Parent" dans la table EditionPossedee (mais problème elle pourrait être NULL...)
    Null est au Modèle Relationnel de Données (alias Théorie Relationnelle) ce qu’est Quasimodo à Phoebus (ou encore Hilarion Lefuneste à Achille Talon). Vox in deserto, je passe mon temps à alerter au sujet de ce porteur de tares, inhibiteur des optimiseurs des SGBD, semeur de m... quant à la logique classique, empêcheur de l’utilisation des lois de De Morgan, etc.
     
    Citation Envoyé par almoha
    La présence de "AnneeParution" dans la table [Edi_Type] ne serait-elle pas redondante car déjà présente dans la table [Edition] ?
    Dans votre MLD, oui, mais pas dans le mien, car dans mon MCD l’entité-type Edition est dépourvue de cet attribut.
     
    Citation Envoyé par almoha
    je ne suis pas sûr de saisir ce que recoupe la notion de "types d'édition" dans la table [EditionType]
     
    Le temps ayant passé, je ne sais plus à quelle règle de gestion cela correspond... Si j’en ai le temps, je repasserai en revue vos règles figurant dans le
    post #53. En attendant, faisons comme si cette partie n’existait pas, jusqu’à ce que le besoin s’en fasse sentir...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  4. #64
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonjour fsmrel,

    Durant le mois écoulé, j’ai continué à réfléchir sur le sujet. J’ai un peu aménagé le MCD :

    - Simplification de la partie relative aux éditions "enfants et parents" des éditions possédées. J’ai opté pour une seule relation réflexive « connecter ». En effet il m’importe seulement de déterminer si une édition est "connectée" à une ou plusieurs autres éditions. C’est le cas si elles se rattachent toutes à la même œuvre et si elles sont toutes possédées (quelle que soit la nature du lien les unissant).

    - Ajout des concepts de langue et de traduction :
    1. Une œuvre est écrite dans une seule langue originale.
    2. Une œuvre peut être traduite dans 0, 1 ou plusieurs langues. Une traduction concerne une seule œuvre et une seule langue.
    3. Une édition est publiée dans une seule langue. Je ne souhaite pas gérer les éditions bilingues.
    4. Un contributeur peut participer à 1 ou à plusieurs éditions. Une édition peut impliquer 1 à plusieurs contributeurs.
    5. Chaque contribution d'un contributeur à une édition est associée à un type de contribution.
    6. Un contributeur peut participer à 0,1 ou à plusieurs traductions. Une traduction peut impliquer 0 à plusieurs contributeurs.

    Le MCD correspondant :

    Nom : Biblio MCD Janv 2025.jpg
Affichages : 125
Taille : 103,5 Ko

    Le MLD textuel qui en découle :
    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
    Editeur = (EditeurId SERIAL, EditeurNom VARCHAR(100) );
    Format = (FormatId SERIAL, FormatLibelle VARCHAR(100) );
    Contributeur = (ContributeurId SERIAL, ContributeurNom VARCHAR(100) );
    ContributionType = (ContributionTypeId SERIAL, ContributionTypeLibelle VARCHAR(100) );
    Langue = (Langueid SERIAL, CodeLangue CHAR(2) , NomLangue VARCHAR(100) );
    Oeuvre = (OeuvreId SERIAL, TitreOriginal VARCHAR(100) , #Langueid);
    Traduction = (#Langueid, #OeuvreId, TitreTraduit VARCHAR(255) );
    Edition = (#OeuvreId, EditionNumero SERIAL, AnneParution DATE, #Langueid, #EditeurId);
    EditionNonPossedee = (#(#OeuvreId, EditionNumero));
    EditionPossedee = (#(#OeuvreId, EditionNumero), ISBN13 VARCHAR(13) , EditionDateAchat DATE, #FormatId);
    Referencer = (#(#(#OeuvreId, EditionNumero)), #(#(#OeuvreId_1, EditionNumero_1)));
    Edi_Con = (#(#(#OeuvreId, EditionNumero)), #ContributeurId, #ContributionTypeId);
    connecter = (#(#(#OeuvreId, EditionNumero)), #(#(#OeuvreId_1, EditionNumero_1)));
    Tra_Con = (#ContributeurId, #(#Langueid, #OeuvreId));
    Le script PostgreSQL de création des tables :
    Code SQL : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    CREATE TABLE Editeur(
       EditeurId SERIAL,
       EditeurNom VARCHAR(100)  NOT NULL,
       PRIMARY KEY(EditeurId),
       UNIQUE(EditeurNom)
    );
     
    CREATE TABLE Format(
       FormatId SERIAL,
       FormatLibelle VARCHAR(100)  NOT NULL,
       PRIMARY KEY(FormatId),
       UNIQUE(FormatLibelle)
    );
     
    CREATE TABLE Contributeur(
       ContributeurId SERIAL,
       ContributeurNom VARCHAR(100)  NOT NULL,
       PRIMARY KEY(ContributeurId)
    );
     
    CREATE TABLE ContributionType(
       ContributionTypeId SERIAL,
       ContributionTypeLibelle VARCHAR(100)  NOT NULL,
       PRIMARY KEY(ContributionTypeId),
       UNIQUE(ContributionTypeLibelle)
    );
     
    CREATE TABLE Langue(
       Langueid SERIAL,
       CodeLangue CHAR(2) ,
       NomLangue VARCHAR(100) ,
       PRIMARY KEY(Langueid)
    );
     
    CREATE TABLE Oeuvre(
       OeuvreId SERIAL,
       TitreOriginal VARCHAR(100)  NOT NULL,
       Langueid INTEGER NOT NULL,
       PRIMARY KEY(OeuvreId),
       FOREIGN KEY(Langueid) REFERENCES Langue(Langueid)
    );
     
    CREATE TABLE Traduction(
       Langueid INTEGER,
       OeuvreId INTEGER,
       TitreTraduit VARCHAR(255)  NOT NULL,
       PRIMARY KEY(Langueid, OeuvreId),
       FOREIGN KEY(Langueid) REFERENCES Langue(Langueid),
       FOREIGN KEY(OeuvreId) REFERENCES Oeuvre(OeuvreId)
    );
     
    CREATE TABLE Edition(
       OeuvreId INTEGER,
       EditionNumero SERIAL,
       AnneParution DATE,
       Langueid INTEGER NOT NULL,
       EditeurId INTEGER NOT NULL,
       PRIMARY KEY(OeuvreId, EditionNumero),
       FOREIGN KEY(OeuvreId) REFERENCES Oeuvre(OeuvreId),
       FOREIGN KEY(Langueid) REFERENCES Langue(Langueid),
       FOREIGN KEY(EditeurId) REFERENCES Editeur(EditeurId)
    );
     
    CREATE TABLE EditionNonPossedee(
       OeuvreId INTEGER,
       EditionNumero INTEGER,
       PRIMARY KEY(OeuvreId, EditionNumero),
       FOREIGN KEY(OeuvreId, EditionNumero) REFERENCES Edition(OeuvreId, EditionNumero)
    );
     
    CREATE TABLE EditionPossedee(
       OeuvreId INTEGER,
       EditionNumero INTEGER,
       ISBN13 VARCHAR(13) ,
       EditionDateAchat DATE,
       FormatId INTEGER NOT NULL,
       PRIMARY KEY(OeuvreId, EditionNumero),
       UNIQUE(ISBN13),
       FOREIGN KEY(OeuvreId, EditionNumero) REFERENCES Edition(OeuvreId, EditionNumero),
       FOREIGN KEY(FormatId) REFERENCES Format(FormatId)
    );
     
    CREATE TABLE Referencer(
       OeuvreId INTEGER,
       EditionNumero INTEGER,
       OeuvreId_1 INTEGER,
       EditionNumero_1 INTEGER,
       PRIMARY KEY(OeuvreId, EditionNumero, OeuvreId_1, EditionNumero_1),
       FOREIGN KEY(OeuvreId, EditionNumero) REFERENCES EditionPossedee(OeuvreId, EditionNumero),
       FOREIGN KEY(OeuvreId_1, EditionNumero_1) REFERENCES EditionNonPossedee(OeuvreId, EditionNumero)
    );
     
    CREATE TABLE Edi_Con(
       OeuvreId INTEGER,
       EditionNumero INTEGER,
       ContributeurId INTEGER,
       ContributionTypeId INTEGER,
       PRIMARY KEY(OeuvreId, EditionNumero, ContributeurId, ContributionTypeId),
       FOREIGN KEY(OeuvreId, EditionNumero) REFERENCES EditionPossedee(OeuvreId, EditionNumero),
       FOREIGN KEY(ContributeurId) REFERENCES Contributeur(ContributeurId),
       FOREIGN KEY(ContributionTypeId) REFERENCES ContributionType(ContributionTypeId)
    );
     
    CREATE TABLE connecter(
       OeuvreId INTEGER,
       EditionNumero INTEGER,
       OeuvreId_1 INTEGER,
       EditionNumero_1 INTEGER,
       PRIMARY KEY(OeuvreId, EditionNumero, OeuvreId_1, EditionNumero_1),
       FOREIGN KEY(OeuvreId, EditionNumero) REFERENCES EditionPossedee(OeuvreId, EditionNumero),
       FOREIGN KEY(OeuvreId_1, EditionNumero_1) REFERENCES EditionPossedee(OeuvreId, EditionNumero)
    );
     
    CREATE TABLE Tra_Con(
       ContributeurId INTEGER,
       Langueid INTEGER,
       OeuvreId INTEGER,
       PRIMARY KEY(ContributeurId, Langueid, OeuvreId),
       FOREIGN KEY(ContributeurId) REFERENCES Contributeur(ContributeurId),
       FOREIGN KEY(Langueid, OeuvreId) REFERENCES Traduction(Langueid, OeuvreId)
    );

    Ci-après un script d’insertion d’un jeu de données qui insère 4 œuvres :

    - 2 œuvres françaises :

    • Titre original « La fille de la nuit » : 2 éditions sont possédées, 1 en poche, 1 en grand format => la relation « connecter » est donc sollicitée ;
    • Titre original « Connemara » : 1 édition possédée (format poche) et 1 édition non possédée (éditeur grand format) => la relation « referencer » est donc sollicitée.

    - 2 œuvres étrangères :

    • Titre original « San Ti » : 1 édition possédée au format poche, traduite en français – titre traduit «Le problème à trois corps » ; 2 éditions non possédées : 1 édition traduite en français et 1 édition en version originale CH => la relation « referencer » est donc sollicitée ;
    • Titre original « Salem’s Lot » : 2 éditions possédées : 1 au format poche, traduite en français – titre traduit «Salem », et 1 au format poche édition originale EN => la relation « connecter » est donc sollicitée ; 1 édition non possédée : édition en version originale EN => la relation « referencer » est donc sollicitée.

    Code SQL : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    INSERT INTO editeur (editeurid, editeurnom) VALUES (1, 'Le Livre de Poche');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (2, 'Le Masque');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (3, 'Babel');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (4, 'Actes Sud');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (5, 'Chongqing');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (6, 'Presses Pocket');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (7, 'Alta');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (8, 'New English Library');
    INSERT INTO editeur (editeurid, editeurnom) VALUES (9, 'DoubleDay');
     
     
    INSERT INTO langue (langueid, codelangue, nomlangue) VALUES (1, 'FR', 'Français');
    INSERT INTO langue (langueid, codelangue, nomlangue) VALUES (8, 'ZH', 'Chinois');
    INSERT INTO langue (langueid, codelangue, nomlangue) VALUES (9, 'EN', 'Anglais');
     
     
    INSERT INTO oeuvre (oeuvreid, titreoriginal, langueid) VALUES (1, 'La fille de la nuit', 1);
    INSERT INTO oeuvre (oeuvreid, titreoriginal, langueid) VALUES (2, 'Connemara', 1);
    INSERT INTO oeuvre (oeuvreid, titreoriginal, langueid) VALUES (9, 'San Ti', 8);
    INSERT INTO oeuvre (oeuvreid, titreoriginal, langueid) VALUES (10, 'Salem''s Lot', 9);
     
     
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (1, 1, '1996-01-01', 1, 2);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (1, 2, '2000-01-01', 1, 1);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (2, 1, '2022-01-01', 1, 4);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (2, 2, '2023-01-01', 1, 3);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (9, 1, '2006-01-01', 8, 5);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (9, 2, '2016-01-01', 1, 4);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (9, 4, '2018-01-01', 1, 3);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (10, 5, '1988-01-01', 1, 6);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (10, 6, '1977-01-01', 1, 7);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (10, 7, '1976-01-01', 9, 8);
    INSERT INTO edition (oeuvreid, editionnumero, anneparution, langueid, editeurid) VALUES (10, 8, '1975-01-01', 9, 9);
     
     
    INSERT INTO format (formatid, formatlibelle) VALUES (1, 'Poche');
    INSERT INTO format (formatid, formatlibelle) VALUES (2, 'Grand format');
    INSERT INTO format (formatid, formatlibelle) VALUES (3, 'Numérique');
     
     
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (1, 1, '9782702478424', '2022-01-01', 2);
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (1, 2, '9782253170075', '2023-01-01', 1);
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (2, 2, '9782330178994', '2023-01-15', 1);
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (9, 4, '9782330113551', '2024-01-15', 1);
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (10, 5, '9782266029612', '1997-01-01', 1);
    INSERT INTO editionpossedee (oeuvreid, editionnumero, isbn13, editiondateachat, formatid) VALUES (10, 7, '9782266029613', '2020-01-01', 1);
     
     
    INSERT INTO connecter (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (1, 1, 1, 2);
    INSERT INTO connecter (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (1, 2, 1, 1);
    INSERT INTO connecter (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (10, 5, 10, 7);
    INSERT INTO connecter (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (10, 7, 10, 5);
     
     
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (1, 'Serge Brussolo');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (2, 'Nicolas Mathieu');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (3, 'Jacques Nabil');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (10, 'Liu Cixin');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (11, 'Gwennaël Gaffric');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (12, 'Stephen King');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (13, 'Christiane Thiollier');
    INSERT INTO contributeur (contributeurid, contributeurnom) VALUES (14, 'Joan Bernard');
     
     
    INSERT INTO contributiontype (contributiontypeid, contributiontypelibelle) VALUES (1, 'Auteur');
    INSERT INTO contributiontype (contributiontypeid, contributiontypelibelle) VALUES (2, 'Traducteur');
    INSERT INTO contributiontype (contributiontypeid, contributiontypelibelle) VALUES (3, 'Illustrateur');
     
     
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (1, 1, 1, 1);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (1, 2, 1, 1);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (2, 2, 2, 1);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (1, 1, 3, 3);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (1, 2, 3, 3);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (9, 4, 10, 1);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (9, 4, 11, 2);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (10, 5, 12, 1);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (10, 5, 13, 2);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (10, 5, 14, 2);
    INSERT INTO edi_con (oeuvreid, editionnumero, contributeurid, contributiontypeid) VALUES (10, 7, 12, 1);
     
     
    INSERT INTO editionnonpossedee (oeuvreid, editionnumero) VALUES (2, 1);
    INSERT INTO editionnonpossedee (oeuvreid, editionnumero) VALUES (9, 1);
    INSERT INTO editionnonpossedee (oeuvreid, editionnumero) VALUES (9, 2);
    INSERT INTO editionnonpossedee (oeuvreid, editionnumero) VALUES (10, 6);
    INSERT INTO editionnonpossedee (oeuvreid, editionnumero) VALUES (10, 8);
     
     
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (2, 2, 2, 1);
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (9, 4, 9, 1);
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (9, 4, 9, 2);
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (10, 5, 10, 6);
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (10, 5, 10, 8);
    INSERT INTO referencer (oeuvreid, editionnumero, oeuvreid_1, editionnumero_1) VALUES (10, 7, 10, 8);
     
     
    INSERT INTO traduction (langueid, oeuvreid, titretraduit) VALUES (1, 10, 'Salem');
    INSERT INTO traduction (langueid, oeuvreid, titretraduit) VALUES (1, 9, 'Le problème à trois corps');
     
     
    INSERT INTO tra_con (contributeurid, langueid, oeuvreid) VALUES (13, 1, 10);
    INSERT INTO tra_con (contributeurid, langueid, oeuvreid) VALUES (14, 1, 10);
    INSERT INTO tra_con (contributeurid, langueid, oeuvreid) VALUES (11, 1, 9);

    Une requête PostgreSQL d’affichage aux fins de test (obtenue avec l’aide d’un générateur) qui montre toutes les données, avec les éditions et leurs liens éventuels :
    Code SQL : 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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    SELECT 
        o.OeuvreId AS "ID Oeuvre",
        o.TitreOriginal AS "Titre Original",
    	t.TitreTraduit AS "Titre Traduit",
        l.CodeLangue AS "Langue Originale",
        l.NomLangue AS "Nom Langue Originale",
        e.EditionNumero AS "Numéro Edition",
        e.AnneParution AS "Année Parution",
        l2.CodeLangue AS "Langue Edition",
        l2.NomLangue AS "Nom Langue Edition",
        ed.EditeurNom AS "Nom Editeur",
        ep.ISBN13 AS "ISBN",
        ep.EditionDateAchat AS "Date Achat",
        f.FormatLibelle AS "Format",
    (
        SELECT STRING_AGG(
            contrib_info,
            '; '
            ORDER BY sort_order, contrib_info
        )
        FROM (
            SELECT DISTINCT ON (c.ContributeurNom, ct.ContributionTypeLibelle)
                CONCAT(c.ContributeurNom, ' (', ct.ContributionTypeLibelle, ')') AS contrib_info,
                CASE 
                    WHEN ct.ContributionTypeLibelle = 'Auteur' THEN 1
                    WHEN ct.ContributionTypeLibelle = 'Traducteur' THEN 2
                    ELSE 3
                END AS sort_order
            FROM Edi_Con ec
            JOIN Contributeur c ON ec.ContributeurId = c.ContributeurId
            JOIN ContributionType ct ON ec.ContributionTypeId = ct.ContributionTypeId
            WHERE ec.OeuvreId = o.OeuvreId AND ec.EditionNumero = e.EditionNumero
            ORDER BY c.ContributeurNom, ct.ContributionTypeLibelle, sort_order
        ) subquery
    ) AS "Nom Contributeur"
    ,
        CASE 
            WHEN ep.OeuvreId IS NOT NULL THEN 'possédée'
            ELSE 'non possédée'
        END AS "Statut",
        COALESCE(cn1.OeuvreId_1, cn2.OeuvreId) AS "Connecté vers OeuvreId",
        COALESCE(cn1.EditionNumero_1, cn2.EditionNumero) AS "Connecté vers EditionNumero",
        STRING_AGG(
            DISTINCT 
            CONCAT(r1.OeuvreId_1, '-', r1.EditionNumero_1),
            '; '
        ) AS "referencevers",
        STRING_AGG(
            DISTINCT 
            CONCAT(r2.OeuvreId, '-', r2.EditionNumero),
            '; '
        ) AS "referencesource"
     
    FROM Edition e
    LEFT JOIN EditionPossedee ep ON e.OeuvreId = ep.OeuvreId AND e.EditionNumero = ep.EditionNumero
    LEFT JOIN Oeuvre o ON e.OeuvreId = o.OeuvreId
    LEFT JOIN Langue l ON o.LangueId = l.LangueId
    LEFT JOIN Langue l2 ON e.LangueId = l2.LangueId
    LEFT JOIN Editeur ed ON e.EditeurId = ed.EditeurId
    LEFT JOIN Format f ON ep.FormatId = f.FormatId
    LEFT JOIN Connecter cn1 ON e.OeuvreId = cn1.OeuvreId AND e.EditionNumero = cn1.EditionNumero
    LEFT JOIN Connecter cn2 ON e.OeuvreId = cn2.OeuvreId_1 AND e.EditionNumero = cn2.EditionNumero_1
    LEFT JOIN Traduction t ON o.OeuvreId = t.OeuvreId AND t.LangueId = l2.LangueId
    LEFT JOIN Referencer r1 ON r1.OeuvreId = ep.OeuvreId AND r1.EditionNumero = ep.EditionNumero
    LEFT JOIN Referencer r2 ON r2.OeuvreId_1 = e.OeuvreId AND r2.EditionNumero_1 = e.EditionNumero
    GROUP BY 
        o.OeuvreId, o.TitreOriginal, l.CodeLangue, l.NomLangue, e.EditionNumero, 
        e.AnneParution, l2.CodeLangue, l2.NomLangue, ed.EditeurNom, ep.ISBN13, 
        ep.EditionDateAchat, f.FormatLibelle, ep.OeuvreId, cn1.OeuvreId_1, 
        cn1.EditionNumero_1, cn2.OeuvreId, cn2.EditionNumero, t.TitreTraduit
    ORDER BY o.OeuvreId, e.EditionNumero;

    Pour le concept de traduction, je m'aperçois que la modélisation ne gère pas le cas où une œuvre fait l'objet de deux éditions dont chacune est traduite par un traducteur différent. Je pense qu'il faudrait que la clé composite de la table Traduction devienne (Langueid, OeuvreId, EditionNumero). A votre avis, comment adapter le MCD pour ce faire ? Je suis également preneur de toutes autres remarques. Merci.
    Fichiers attachés Fichiers attachés

  5. #65
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut Looping et génération contrainte Unique
    Bonjour,

    Je continue à réfléchir sur la modélisation de l'inventaire de mes livres. J'utilise Looping pour concevoir le MCD. Je travaille actuellement sur le concept suivant : la possibilité pour chaque lecteur de mettre en favori un exemplaire particulier d'une édition.

    La règle de gestion est la suivante : Chaque lecteur a zéro ou plusieurs favoris ; chaque exemplaire peut être marqué favori zéro ou une fois ; une entrée favori concerne exactement un lecteur et un exemplaire et est identifiée par eux.

    Le MCD correspondant :
    Nom : MCD-favori-lecteur-exemplaire.jpg
Affichages : 73
Taille : 51,6 Ko

    Mon interrogation porte sur le LDD généré par Looping, concernant la table favori :
    Code sql : 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
     
    CREATE TABLE oeuvre(
       oeuvre_id BIGSERIAL,
       titre_original TEXT NOT NULL,
       lien_web_critique TEXT NULL,
       PRIMARY KEY(oeuvre_id)
    );
     
    CREATE TABLE edition(
       oeuvre_id BIGSERIAL,
       edition_numero INT CHECK(edition_numero > 0),
       titre_edition TEXT NULL,
       isbn13 VARCHAR(13) NULL,
       annee_parution INT NOT NULL CHECK(annee_parution > 0),
       nombre_pages INT NULL CHECK(nombre_pages IS NULL OR nombre_pages > 0),
       format_id INT format(format_id) NULL REFERENCES ON DELETE SET NULL,
       url_image_couverture TEXT NULL,
       est_premiere_edition LOGICAL DEFAULT NULL FALSE,
       details_edition_speciale TEXT NULL,
       PRIMARY KEY(oeuvre_id, edition_numero),
       UNIQUE(isbn13),
       FOREIGN KEY(oeuvre_id) REFERENCES oeuvre(oeuvre_id)
    );
     
    CREATE TABLE lecteur(
       lecteur_id COUNTER,
       nom_lecteur TEXT NOT NULL,
       PRIMARY KEY(lecteur_id),
       UNIQUE(nom_lecteur)
    );
     
    CREATE TABLE exemplaire(
       oeuvre_id BIGSERIAL,
       edition_numero INT,
       exemplaire_numero INT CHECK(exemplaire_numero > 0),
       date_achat DATE NOT NULL,
       PRIMARY KEY(oeuvre_id, edition_numero, exemplaire_numero),
       FOREIGN KEY(oeuvre_id, edition_numero) REFERENCES edition(oeuvre_id, edition_numero)
    );
     
    CREATE TABLE favori(
       oeuvre_id BIGSERIAL,
       edition_numero INT,
       exemplaire_numero INT,
       lecteur_id INT,
       date_ajout_favori DATE NOT NULL DEFAULT CURRENT_DATE,
       PRIMARY KEY(oeuvre_id, edition_numero, exemplaire_numero, lecteur_id),
       UNIQUE(oeuvre_id, edition_numero, exemplaire_numero),
       FOREIGN KEY(oeuvre_id, edition_numero, exemplaire_numero) REFERENCES exemplaire(oeuvre_id, edition_numero, exemplaire_numero),
       FOREIGN KEY(lecteur_id) REFERENCES lecteur(lecteur_id)
    );
    Je ne comprends pas pourquoi la contrainte UNIQUE suivante est générée : UNIQUE(oeuvre_id, edition_numero, exemplaire_numero). Avec cette contrainte UNIQUE, on impose qu'un exemplaire ne peut être le favori que d'un seul lecteur, ce qui ne correspond pas au MCD. Le but est que chaque lecteur puisse avoir sa propre liste de favoris, même si plusieurs lecteurs aiment le même exemplaire. La contrainte d'unicité étant déjà garantie par la clé primaire composite, je m'interroge donc sur cette contrainte unique, superfétatoire et contraire à la logique recherchée, générée par Looping. Qu'en pensez-vous ? Merci.

  6. #66
    Membre Expert
    Avatar de Paprick
    Homme Profil pro
    Professeur des Universités
    Inscrit en
    Juin 2019
    Messages
    747
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Professeur des Universités
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2019
    Messages : 747
    Par défaut
    Bonjour,
    La clé alternative ajoutée à la table "favori" est due à votre cardinalité 0,1.
    En effet, si un exemplaire ne peut concerner qu'un seul favori, alors l'identifiant de l'exemplaire est suffisant pour identifier de façon unique chaque élément de "favori".
    Donc, 2 possibilités :
    • Soit passer cette cardinalité à 0,n et la clé alternative va disparaître.
    • Soit passer la cardinalité 1,1(R) rattachée à "inscrire_favori" à 1,1 et votre clé alternative va devenir clé primaire.

    Mais, dans sa configuration actuelle, votre MCD n'est pas cohérent, puisque la clé primaire de la table "favori" est pas minimale compte tenu de la présence de la cardinalité 0,1.
    Patrick Bergougnoux - Professeur des Universités au Département Informatique de l'IUT de Toulouse III
    La simplicité est la sophistication suprême (Léonard de Vinci)
    LIVRE : Modélisation Conceptuelle de Données - Une Démarche Pragmatique
    Looping - Logiciel de modélisation gratuit et libre d'utilisation

  7. #67
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Salve,

     
    Citation Envoyé par almoha
    Je ne comprends pas pourquoi la contrainte UNIQUE suivante est générée : UNIQUE(oeuvre_id, edition_numero, exemplaire_numero). Avec cette contrainte UNIQUE, on impose qu'un exemplaire ne peut être le favori que d'un seul lecteur, ce qui ne correspond pas au MCD.
     
    La contrainte que vous contestez est bien la conséquence de votre modélisation. En effet, votre représentation :
     
    [Exemplaire]--0,1--(concerner)--(1,1)R--[favori]
     
    est sans équivoque à ce sujet, un favori est la chose d’un exemplaire.

    3e possibilité...

    Si vous préférez privilégier le lecteur en temps que possesseur d’un favori, vous pouvez modéliser ainsi :
     
    [lecteur]--1,n--(inscrire)--(1,1)R--[favori]--1,1--(concerner)--0,1--[Exemplaire]
     
    Où [favori] est à doter d’un attribut identifiant relatif favori_id, puisqu’un lecteur peut avoir plus d’un favori.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  8. #68
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Merci à tous les deux. Vos explications ont mis en lumière le fait que je me suis emmêlé les crayons. Un exemplaire peut en fait être concerné par zéro ou plusieurs enregistrements "Favori" (potentiellement un par lecteur). En passant la cardinalité à 0,n, la clé alternative disparaît effectivement tout naturellement. Je vais choisir cette option parmi les 3 proposées, car c'est celle qui me parle le plus.

  9. #69
    Membre Expert
    Avatar de Paprick
    Homme Profil pro
    Professeur des Universités
    Inscrit en
    Juin 2019
    Messages
    747
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Professeur des Universités
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2019
    Messages : 747
    Par défaut
    Et, compte tenu des 2 identifiants relatifs de part et d'autre, "favori" est en fait une association 0,n/1,n entre "exemplaire" et "lecteur" .
    Patrick Bergougnoux - Professeur des Universités au Département Informatique de l'IUT de Toulouse III
    La simplicité est la sophistication suprême (Léonard de Vinci)
    LIVRE : Modélisation Conceptuelle de Données - Une Démarche Pragmatique
    Looping - Logiciel de modélisation gratuit et libre d'utilisation

  10. #70
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut Modélisation session de lecture
    Bonjour,

    J'ai réfléchi sur la modélisation de sessions de lecture d'un livre (au sens de l'exemplaire d'une édition d'une œuvre). La session de lecture commence à la date du début de la lecture (statut "en cours") et peut s'achever lorsque la lecture est abandonnée (statut "Abandonnée") ou terminée (statut "Terminée").

    - Chaque lecteur peut faire 0 ou N sessions de lecture, mais chaque session est faite par 1 seul lecteur.

    - Chaque exemplaire peut avoir 0 ou N sessions associées, mais chaque session concerne 1 seul exemplaire.

    - Chaque session a 1 statut, un statut peut qualifier 0 ou N sessions (= lecture "En cours'', ''Terminée'', ''Abandonnée").

    Un même livre peut être lu par plusieurs lecteurs, voire relus par les mêmes lecteurs. Je souhaite donc implémenter une historisation des sessions de lecture.

    J'ai conçu le MCD suivant :


    Nom : Focus_lecture.jpg
Affichages : 49
Taille : 57,5 Ko

    Le script LDD généré par Looping :

    Code sql : 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
    55
    56
    57
    58
    59
     
    CREATE TABLE lecteur(
       lecteur_id SERIAL,
       nom_lecteur TEXT NOT NULL,
       CONSTRAINT PK_lecteur PRIMARY KEY(lecteur_id),
       CONSTRAINT AK_lecteur UNIQUE(nom_lecteur)
    );
     
    CREATE TABLE session_statut(
       session_statut_id SERIAL,
       libelle_statut TEXT NOT NULL,-- Ex: ''En cours'', ''Terminée'', ''Abandonnée'
       CONSTRAINT PK_session_statut PRIMARY KEY(session_statut_id),
       CONSTRAINT AK_session_statut UNIQUE(libelle_statut)
    );
     
    CREATE TABLE oeuvre(
       oeuvre_id BIGSERIAL,
       titre_original TEXT NOT NULL,
       CONSTRAINT PK_oeuvre PRIMARY KEY(oeuvre_id)
    );
     
    CREATE TABLE edition(
       oeuvre_id BIGSERIAL,
       edition_numero INTEGER,
       titre_edition TEXT NULL,
       isbn13 VARCHAR(13) NULL,
       annee_parution INTEGER NOT NULL,
       CONSTRAINT PK_edition PRIMARY KEY(oeuvre_id, edition_numero),
       CONSTRAINT AK_edition UNIQUE(isbn13),
       CONSTRAINT FK_edition_oeuvre FOREIGN KEY(oeuvre_id) REFERENCES oeuvre(oeuvre_id)
    );
     
    CREATE TABLE exemplaire(
       oeuvre_id BIGSERIAL,
       edition_numero INTEGER,
       exemplaire_numero INTEGER,
       emplacement TEXT NULL,
       date_achat DATE NOT NULL,
       notes TEXT NULL,
       prix_achat NUMERIC(10,2) NOT NULL,
       CONSTRAINT PK_exemplaire PRIMARY KEY(oeuvre_id, edition_numero, exemplaire_numero),
       CONSTRAINT FK_exemplaire_edition FOREIGN KEY(oeuvre_id, edition_numero) REFERENCES edition(oeuvre_id, edition_numero)
    );
     
     
    CREATE TABLE lecture_session(
       session_id BIGSERIAL,
       date_debut DATE NOT NULL,
       date_fin DATE NULL,
       notes_session TEXT NULL,
       oeuvre_id BIGSERIAL NOT NULL,
       edition_numero INTEGER NOT NULL,
       exemplaire_numero INTEGER NOT NULL,
       session_statut_id INTEGER NOT NULL,
       lecteur_id INTEGER NOT NULL,
       CONSTRAINT PK_lecture_session PRIMARY KEY(session_id),
       CONSTRAINT FK_lecture_session_exemplaire FOREIGN KEY(oeuvre_id, edition_numero, exemplaire_numero) REFERENCES exemplaire(oeuvre_id, edition_numero, exemplaire_numero),
       CONSTRAINT FK_lecture_session_session_statut FOREIGN KEY(session_statut_id) REFERENCES session_statut(session_statut_id),
       CONSTRAINT FK_lecture_session_lecteur FOREIGN KEY(lecteur_id) REFERENCES lecteur(lecteur_id)

    Selon vous, cette modélisation répond-elle aux attentes ? Merci.

  11. #71
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,

    L’éternel problème de la modélisation de la date de fin...

    Disons qu’il doit y avoir une contrainte signifiant que si le statut d’une "lecture_session" est 'Terminée' ou 'Abandonnée', la date de fin doit être renseignée, et qu’elle ne doit pas l’être si le statut est 'En cours'.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  12. #72
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonjour almoha,

    Pour aérer la lecture, je renomme session_statut_id en statut et les dates en debut et fin.

    Supposons que "statut = 1" pour "en cours", "statut = 2" pour "terminée", "statut = 3" pour "abandonnée".

    On peut alors doter la table session d’une contrainte, nommons-la C1 :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE session ADD CONSTRAINT C1 
      CHECK (statut = 1 AND fin IS NULL OR statut <> 1 and fin IS NOT NULL AND debut <= fin) ;
    Noter qu’on s’assure en plus que la date de fin n’est pas antérieure à la date de début.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #73
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonjour fsmrel,

    Merci pour la contrainte qui remplit parfaitement son office de garde-fou.

    D'après mes tests, la modélisation proposée couvre bien ma problématique : chaque livre peut être lu, relu par un ou plusieurs lecteurs. Le concept de "session de lecture" suppose que le lecteur indique obligatoirement la date du début de sa lecture (date_debut DATE NOT NULL). Il est donc admis dans ce scénario que le lecteur connaît exactement cette date et qu'il indiquera ensuite celle de l'abandon ou de fin lecture. Il existe néanmoins un autre scénario (courant) : s'agissant d'un livre lu il y a longtemps, le lecteur peut très bien ne pas avoir conservé de trace du cycle de sa lecture : il sait simplement qu'il l'a terminée ou abandonnée. Il ignore la date du début de sa lecture, tout juste peut-il estimer l'année de lecture (ou d'abandon).

    J'ai ajouté ce concept dans le MCD (titres en jaune) en le calquant sur celui de "session de lecture" :


    Nom : Focus_lecture2.jpg
Affichages : 41
Taille : 30,8 Ko

    Il y a peut-être moyen de procéder plus simplement, plutôt que de dupliquer des concepts très proches. Qu'en pensez-vous ? Merci.

  14. #74
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,

    Entité-type "lecture_historique" :le qualificatif "historique" n’est pas approprié dans la mesure où il sous-entend justement date de début et date de fin. Je remplacerais plutôt par quelque chose du genre "reminiscence", "souvenir"... 

    L’association"enregistrer_historique" fait référence à l’entité-type "exemplaire", donc à une date d’achat précise et transitivement à un ISBN, etc., est-ce ainsi qu’il faut interpréter les choses ? D’un autre côté si l’on peut considérer, par exemple, que le lecteur ne se souvient que du titre de l’oeuvre (ce qui est mon cas, quand je pense à Patapoufs et Filifers, le 1er ouvrage que j’ai su lire tout seul, et dont je me souviens parfaitement du lieu et de l’année), ne faudrait-il pas plutôt envisager d’établir un lien entre "lecture_historique" et "oeuvre" ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  15. #75
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonsoir fsmrel,

    Effectivement le qualitatif "historique" n'est pas adapté, je vais prévoir de le changer dans le MCD.

    Je confirme que le lien doit s'établir avec l’entité-type "exemplaire". En effet, c'est de l'objet livre que pourra émaner le possible souvenir de lecture. Le lecteur n'a certes pas noté les dates de début et de fin lecture, mais peut-être la consultation de l'exemplaire en sa possession pourra faire surgir des informations lui permettant d'estimer au plus juste l'année de lecture (le lecteur sait par exemple avoir acquis le livre neuf dès sa parution et se souvient l'avoir lu dans la foulée, il peut donc déduire l'année de lecture à partir de la date de parution; ou le lecteur se "revoit" lire tel livre de sa bibliothèque, en un endroit particulier (un lieu de vacances ?) lui permettant de déterminer une temporalité assez précise (les vacances en Bretagne ? il se souvient que c'était en 2005 ou 2006...); enfin, le lecteur peut parfois retrouver dans un de ses livres un ticket de caisse un peu délavé, laissant néanmoins entrevoir l'information relative à l'année d'achat, et de là peut-être pourra-t-il en déduire l'année de lecture ?

    Une autre modélisation pourrait-elle passer par un héritage : une entité "lecture" dont hériteraient une entité "lecture_tracee" (dates de début et de fin connues) et une entité "lecture_souvenir" (année de lecture seulement) ? Pas sûr de la pertinence. Une autre idée de modélisation peut-être ? A moins que celle prévue dans le MCD ne fasse finalement l'affaire

  16. #76
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut Au choix...
    Bonjour almoha,

    Je propose 3 MCD. J’ai un léger faible pour la spécialisation.
    Autant c’est simple en relationnel pur, dans les 3 cas le problème est celui de la traduction des contraintes (totalité, exclusion) en SQL...
    Comme disait Laspalès à Chevallier, c’est vous qui voyez...


    ------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------

    ------------------------------------------------------------------------------------------------------
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  17. #77
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonsoir fsmrel,

    Le 3e MCD mettant en œuvre la spécialisation aurait mes faveurs. Mais la difficulté à traduire en SQL la contrainte de partition (qui certes pourrait être traitée au niveau de la programmation de l'application) m'incite plutôt à rester sur la modélisation initiale sans héritage. Cela vous paraît-il une bonne option ?

  18. #78
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,

    Si vous revenez au premier MCD, le problème des contraintes demeure !
    Vous avez le choix entre Charybde et Scylla
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  19. #79
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    402
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 402
    Par défaut
    Bonjour fsmrel,

    Vous avez raison, bien sûr, le problème de la contrainte existe toujours dans ce scénario . A la réflexion néanmoins, je me rends compte que la contrainte dont il est question n'est pas pertinente dans ma modélisation : en effet le fait qu'un livre ait été lu "en 1995" (enregistré dans lecture_souvenir) n'empêche logiquement pas de le relire aujourd'hui et de tracer cette nouvelle lecture dans lecture_session. Les deux informations peuvent coexister et représentent des aspects différents de l'historique de lecture de cet exemplaire. Je vais donc en rester à ma modélisation initiale, sans contrainte particulière.

  20. #80
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 176
    Billets dans le blog
    16
    Par défaut
    Bonsoir almoha,

    Citation Envoyé par almoha
    le fait qu'un livre ait été lu "en 1995" (enregistré dans lecture_souvenir) n'empêche logiquement pas de le relire aujourd'hui et de tracer cette nouvelle lecture dans lecture_session
    Tout à fait d'accord ! Mais cette nouvelle lecture ne rendrait-elle pas obsolète celle de 1995, laquelle pourrait alors être effacée ?  

    Comme disait Laspalès à Chevalier...

    P.S. Pour sortir un peu du sujet, quoique... Dans les années 90, Chris Date et Hugh Darwen ont poussé fort loin l’étude du concept de Type (Inheritance Model). Ils étaient partis sur le type "Book" (qui sans doute vous inspirerait !) et ont vite compris que cela serait source de commentaires, controverses, discussions byzantines à n’en plus finir avec d’autres théoriciens. Sagement ils ont élaboré leur théorie du type en l’illustrant en bonne partie avec celui de "Figure plane" (cf. The New Relational Database Dictionary, une centaine de pages consacrées à ce sujet, dont je n’ai pas du reste pas terminé la lecture, entamée il y a 20 ans ). Si un jour les ellipses et les polygones vous inspirent, nonobstant leur caractère dénué de toute fantaisie...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. Mld pour inventaire livre
    Par cold-apok dans le forum Schéma
    Réponses: 1
    Dernier message: 25/09/2007, 01h42
  2. [langage] Je cherche un bon livre ?
    Par Anonymous dans le forum Langage
    Réponses: 13
    Dernier message: 09/04/2003, 13h16
  3. [web] Cherche un conseil pour un livre perl-tk
    Par Anonymous dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 29/04/2002, 15h35
  4. Réponses: 2
    Dernier message: 17/03/2002, 19h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo