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

Diagrammes de Classes Discussion :

Avis pour améliorer un diagramme de classe


Sujet :

Diagrammes de Classes

  1. #1
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut Avis pour améliorer un diagramme de classe
    Bonjour à tous !
    J’essaie de modéliser une base de données pour la gestion des carrières d’une administration. Le modèle répond aux spécifications suivantes :
    • Les agents de l’administration sont constitués en corps de métier. Chaque corps est divisé en classes qui comprennent elles-mêmes un certain nombre d’échelons. Un échelon peut se retrouver dans plusieurs classes, tout comme une classe peut se retrouver dans plusieurs corps.
    • A un instant donné, un agent appartient à un corps, est titulaire d’une classe de ce corps et relève d’un échelon au sein de cette classe.
    • L’accès à un corps et l’avancement d’échelon à échelon ou de classe à classe sont effectifs à la suite d’un acte émanant de l’autorité. Un acte peut concerner plusieurs agents. Au cours de sa carrière, un agent peut aussi bénéficier de plusieurs actes. L’acte d’engagement permet à un nouvel agent d’intégrer l’administration. L’acte de reclassement permet à un agent déjà en activité de changer de corps. L’acte d’avancement permet comme son nom l’indique à un agent d’avancer d’échelon ou de classe.
    • En plus d’être répartis en hiérarchies, les corps sont également classés dans des cadres lorsqu’ils participent d’un même service administratif. Ainsi, chaque corps se trouve dans un cadre et un cadre peut regrouper plusieurs corps. Le décret qui porte organisation d’un cadre constitue le statut particulier de ce cadre. Les statuts particuliers des cadres définissent la hiérarchie des classes dans chaque corps, le nombre d’échelons de chaque classe, le minimum d’ancienneté de services effectifs exigible dans chaque corps pour être promu à la classe supérieure, la durée du temps à passer dans chaque échelon.
    J’ai réalisé une première esquisse du modèle et compte sur la communauté pour le corriger et l’améliorer. Mes préoccupations concernant ce modèle sont les suivantes :
    • Les boucles ainsi constituées sont-elles normales ?
    • La classe Acte ne doit-elle pas être en relation avec les classes Agent, Corps, Classe et Echelon ?
    • La classe Decret ne doit-elle pas être en relation avec les Hiérarchie, Corps, Classe, Echelon ?
    Images attachées Images attachées  

  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonjour mossane,


    On ne v a pas tout traiter en même temps, mais voyons le cas de la classification et celui de la situation des agents.

    Mathématiquement parlant, à un numéro de classe correspondent plusieurs numéros d’échelons et à un numéro d’échelon peuvent correspondre plusieurs numéros de classes. Mais d’un point de vue sémantique, autant une classe compote plusieurs échelons, autant un échelon appartient à une seule classe : il en va des échelons comme des lignes facture, certes le numéro de ligne de facture 1 se retrouve dans toutes les factures, mais néanmoins on modélise plutôt ainsi les lignes de facture :

    [FACTURE]◄► ----1,1--------------------------1,N----[LIGNE FACTURE]


    Même observation quant à la composition des corps en classes.

    Autrement dit, pour connaître à la date T quel est le corps ou la classe ou d’un agent, il suffit de connaître son échelon à cette date (sous-entendu dans la classe de l’échelon et le corps de la classe) :




    Par exemple, pour savoir à quelle date un agent a intégré tel corps, on le saura en fonction de la date d’effet la plus ancienne (attribut DateEffet de la classe AGENT_ECHELON).

    Dans vote diagramme, du fait de la présence de l’association entre CORPS et CLASSE, rien n’empêche qu’un agent fasse partie d’une classe qui n’a rien à voir avec celles qui sont référencées par les échelons qu’il a gravis (même chose quant aux corps, mutatis mutandis).
    (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.

  3. #3
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,
    Je m'excuse du retard. Je dois avouer que j'ai mis un peu de temps avant de comprendre votre modèle (si je l'ai compris bien sur). Dans mon raisonnement, je me disais que le fait de voir apparaître plusieurs fois le même libellé de classe (2eme classe par exemple) autant de fois qu'il existe dans les différents corps est une redondance. Mais, vous avez tout à fait raison quand vous dites qu'une classe appartient à un seul corps. Même constat pour les échelons.
    Un grand merci à vous fsmrel. A moi tout seul, je n'aurais pas fait mieux.
    J'ai pris en compte vos remarques et créé la version 2 du diagramme.
    J'ai remplacé la classe DECRET par la classe TEXTE plus générale, puisqu'à la place d'un décret, on peut avoir une loi ou une instruction.
    J'ai aussi introduit une nouvelle classe CADRE_CORPS. En effet, un texte est lié à un cadre et peut concerner ou pas tous les corps de ce cadre. Un corps peut aussi être défini par plusieurs textes.
    Enfin, j'ai défini certains points que je n'avais pas abordés dans le premier modèle tels que le nombre d'échelons d'une classe (variable d'une classe à une autre), la durée d'un échelon ou encore le minimum d'ancienneté exigible dans chaque corps pour être promu à la classe supérieure, etc.
    Merci !
    Images attachées Images attachées  

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Votre diagramme prend une bonne tournure.

    Quelques remarques quand même :

    1) Qu’est-ce qu’une position ? L’association entre AGENT et POSITION a perdu ses multiplicités. Quoi qu’il en soit, je suppose qu’à une date donnée un agent a une position et une seule. C’est cela ?

    2) Vous dites que les corps sont hiérarchisés. Là aussi les multiplicités ont disparu. Cela dit, qui dit hiérarchie dit en général association réflexive : tel corps dépend de tel autre corps (un et un seul), lequel peut être une référence pour plusieurs corps, auquel cas on modélise une arborescence. Qu’en est-il dans votre contexte ?

    Exemple auquel je pense :



    Variante :




    3) Cas de la classe CADRE_CORPS

    La classe CADRE_CORPS donne le sentiment très net d’une association ternaire entre les classes CADRE, CORPS et TEXTE. S’il en est bien ainsi, alors des multiplicités portées par les associations de CADRE_CORPS avec ces trois classes, on infère les règles suivantes :

    a) A un instant donné, pour un cadre et un corps donnés, on peut faire référence à plusieurs textes.

    b) A un instant donné, pour un cadre et un texte donnés, on peut faire référence à plusieurs corps.

    c) A un instant donné, pour un corps et un texte donnés, on peut faire référence à plusieurs cadres.

    Qu’en est-il ?


    Bon courage
    (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.

  5. #5
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,
    Je ne m’étais pas rendu compte de la disparition des multiplicités. Je les ai remises en place.

    1) Tout agent est placé dans l’une des positions suivantes : en activité, en détachement, en disponibilité, etc. Donc, vous avez bien vu, en une date donnée, un agent a une position et une seule, mais dans le temps, il peut avoir plusieurs positions.

    2) Par hiérarchie, j’entends plutôt catégorie (catégorie : A, B, etc.). Les corps sont répartis en cinq hiérarchies : A, B, C, D et E. Il y a certains corps qui peuvent appartenir à plusieurs hiérarchies.

    3) 3) En réalité, ce n’est pas une association ternaire que j’ai voulu modéliser. La relation entre CADRE, CORPS et TEXTE est un peu complexe.
    Le cadre regroupe des corps qui participent au fonctionnement d’un même service administratif. Par exemple dans le cadre Enseignement général, on peut retrouver les corps suivants : Professeurs de l’enseignement secondaire, Inspecteurs de l’enseignement élémentaire, Instituteurs, etc. Un corps appartient à un cadre et un seul.

    Les cadres et corps sont organisés par un texte (un décret le plus souvent). Le ou les texte(s) qui porte(nt) organisation d’un cadre constitue(nt) le statut particulier de ce cadre. On retrouve quelques cadres qui ne se rapportent à aucun texte.
    De façon générale, même si ce n’est pas toujours le cas, un corps hérite du ou des texte(s) définissant le statut particulier du cadre auquel il se rapporte.

    En plus des cadres, on peut également différencier les corps suivant leur type : corps fonctionnaires, corps non-fonctionnaires, corps paramilitaires, etc. C’est pourquoi, je propose que l’attribut CorpsType de la classe CORPS soit promu en une classe CORPS_TYPE. Des corps appartenant à un même cadre peuvent être de types différents. Par exemple, il existe des enseignants fonctionnaires et des enseignants non-fonctionnaires. Un texte (ou plusieurs) peut définir le statut d’un type de corps. Tout comme avec les cadres, de manière générale, un corps hérite du texte définissant le statut du type auquel il se rapporte. Mais ce n’est pas toujours le cas.

    En définitive, un corps se réfère toujours au moins à un texte qu’il hérite de son cadre et/ou de son type ou qui lui est appliqué indépendamment de ses cadre et corps.

    Un nouveau texte peut abroger ou modifier un texte déjà existant. Ce qui, je pense, implique une association réflexive qui n’apparait pas, car mon logiciel (Argouml) ne me le permet pas.

    La classe DIVISION est là à titre administratif. Il existe une division qui s’occupe des fonctionnaires, une deuxième qui s’occupe des non-fonctionnaires et une troisième qui s’occupe des enseignants bien que l’on trouve parmi ces derniers des fonctionnaires et des non-fonctionnaires.

    J’ai donc modifié la modélisation pour prendre en compte cette nouvelle donne.
    Je suis très réconforté par vos encouragements. Merci !
    Images attachées Images attachées  

  6. #6
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    HIERARCHIE

    D’accord pour la hiérarchie.


    TEXTE

    Un texte pouvant abroger ou modifier un autre texte, il y a effectivement une association réflexive.


    POSITION

    Puisqu’à un instant donné un agent n’a qu’une position et ne se situe que dans lieu (à moins d’avoir le don de bilocation ), je verrai plutôt la représentation suivante :



    La classe DATE n’a en réalité pas à faire l’objet d’une génération particulière : si vous dérivez le diagramme en modèle de type SQL, inutile de conserver une table DATE qui ne servira à rien. Diagramme dérivé :




    La paire {AgentId, DatePosition} est clé de la table AGENT_POSITION, la contrainte dont il est question est donc bien respectée.


    CORPS, CADRE, CORPS_TYPE

    Puisqu’un corps détermine un cadre et un type de corps, ceci doit figurer dans le diagramme :




    Si les textes portent spécifiquement soit sur les cadres et les corps-types, on pourrait envisager une spécialisation des textes :



    On y arrivera !



    N'hésitez pas à voter quand une réponse vous a paru utile...
    (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.

  7. #7
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,

    Mieux vaut tard que jamais. Je n'avais pas fait attention au vote, mais toutes les réponses m'ont été d'une grande utilité.

    POSITION

    D'accord pour la position.

    CADRE, CORPS, CORPS_TYPE, TEXTE

    Je trouve que la généralisation peut faire l'affaire.Nom : administration4.jpg
Affichages : 3787
Taille : 40,3 Ko


    Seulement, j'ai encore un souci par rapport à cette solution. Je vois qu' un cadre, corps ou corps_type peut directement se référer à un texte. Mais, est-ce qu'un corps pourra se référer indirectement à un texte via son cadre ou type de corps ?

    En fait, un texte portant organisation d'un cadre ou un type de corps peut concerner ou pas tous les corps de ce cadre ou type de corps.

  8. #8
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Citation Envoyé par mossane Voir le message
    Je vois qu' un cadre, corps ou corps_type peut directement se référer à un texte. Mais, est-ce qu'un corps pourra se référer indirectement à un texte via son cadre ou type de corps ?
    Dans l’état du diagramme, un corps C détermine un cadre et ce cadre peut faire l’objet de plusieurs textes : si seuls certains de ces textes sont pertinents pour le corps C, dans l’état du diagramme on ne sait pas dire quels sont ces textes.

    Est-ce bien là le problème ?
    (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.

  9. #9
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonsoir fsmrel,

    Oui, c'est bien là mon problème.

    Un corps C détermine un cadre et ce cadre peut faire l'objet de plusieurs textes. Plusieurs de ces textes (ou aucun) peuvent être pertinents pour le corps.

    J'ai pensé à la solution suivante :


    Nom : administration5.jpg
Affichages : 2075
Taille : 15,4 Ko


    Est-ce juste ?

  10. #10
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Il y a un problème avec votre représentation, car on n’y voit plus l’association directe entre TEXTE_CADRE et CADRE : désormais un texte cadre peut donc a priori faire référence à plusieurs cadres alors qu’un texte cadre doit déterminer un cadre. Qui plus est, un texte cadre doit pouvoir concerner un cadre indépendamment des corps, ce qui n’est plus le cas.

    Pour ma part, je partirais plutôt des diagrammes antérieurs, en ajoutant une association de type plusieurs à plusieurs connectant TEXTE_CADRE et CORPS, association qu’on peut nommer TEXTE_CADRE_CORPS. Si un texte cadre continue à faire référence à un et un seul cadre, et certains corps de ce cadre font référence à ce texte cadre (sachant qu’un corps peut faire référence à plusieurs textes cadres (sous-entendu du cadre dont ils font partie), alors on peut représenter les choses de la façon suivante :




    Mais attention ! On peut naviguer de deux façons en partant de TEXTE_CADRE pour atteindre CADRE : soit en empruntant le chemin allant directement de TEXTE_CADRE à CADRE, soit en empruntant le chemin passant par CORPS, mais alors rien ne garantit que le cadre qu’on atteint est celui qui est défini par TEXTE_CADRE....

    Exemple tabulaire (clés soulignées)

    On a deux cadres, ca1 et ca2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CADRE 
    CadreId    
    -------
    ca1
    ca2
    On a des textes cadres qui vont bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TEXTE_CADRE
    TexteId    CadreId
    -------      
    t1         ca1
    t2         ca2
    Des corps :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CORPS
    CorpsId    CadreId    CorpsTypeId
    -------                
    co1        ca1        coty1
    co2        ca2        coty2
    Des associations relationnellement légales entre des textes cadres (TEXTE_CADRE)et des corps (CORPS) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TEXTE_CADRE_CORPS
    TexteId    CorpsId
    -------    ------- 
    t1         co2
    Trouvez l’erreur...

    Moralité : il faudra se doter des moyens interdisant automatiquement cette situation. Si par exemple vous utilisez un SGBD SQL, il faudra mettre en œuvre les trigger ad-hoc.
    (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.

  11. #11
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonsoir fsmrel,

    Je vois que le corps co2 fait référence à un texte t1 qui détermine un cadre ca1 dont il (co2) ne fait pas parti. Néanmoins, on peut conserver cette représentation. Je compte implémenter la base sous Mysql. Je verrai comment interdire cette situation avec les triggers.

    La logique qui unit les classes TEXTE_CADRE, CADRE et CORPS est la même que celle qui unit les classes TEXTE_CORPS_TYPE, CORPS_TYPE et CORPS. J'ai donc ajouté une association de plusieurs à plusieurs entre TEXTE_CORPS_TYPE et CORPS.

    J'ai aussi conservé la classe TEXTE_CORPS pour permettre à un corps de faire référence à un texte indépendamment de son cadre ou de son type de corps.

    Je ne voudrais pas abuser de votre disponibilité trop longtemps. Mais si la représentation ci-dessous est validée, j'aimerais revenir sur deux points pour avoir le diagramme en intégralité. L'un est relatif aux classes et échelons et l'autre aux agents et actes.

    Nom : administration6.jpg
Affichages : 3912
Taille : 45,0 Ko

    Merci !

    NB : j'ai obtenu mon premier point lors de cette discussion.

  12. #12
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Citation Envoyé par mossane Voir le message
    Je vois que le corps co2 fait référence à un texte t1 qui détermine un cadre ca1 dont il (co2) ne fait pas partie
    Vous avez donc bien vu ^^


    Citation Envoyé par mossane Voir le message
    Je compte implémenter la base sous Mysql. Je verrai comment interdire cette situation avec les triggers.
    D’accord. Si vous avez des problèmes avec les triggers, je pourrai vous aider.


    Citation Envoyé par mossane Voir le message
    La logique qui unit les classes TEXTE_CADRE, CADRE et CORPS est la même que celle qui unit les classes TEXTE_CORPS_TYPE, CORPS_TYPE et CORPS. J'ai donc ajouté une association de plusieurs à plusieurs entre TEXTE_CORPS_TYPE et CORPS.
    D’accord, on est dans un parfait mutatis mutandis comme disait mon voisin du dessus.

    Citation Envoyé par mossane Voir le message
    J'ai aussi conservé la classe TEXTE_CORPS pour permettre à un corps de faire référence à un texte indépendamment de son cadre ou de son type de corps.
    Pas d’objection.


    Citation Envoyé par mossane Voir le message
    si la représentation ci-dessous est validée
    De mon côté c’est validé.


    Citation Envoyé par mossane Voir le message
    j'aimerais revenir sur deux points
    Comme disait encore mon voisin du dessus : « timeo ! », mais revenons...


    Citation Envoyé par mossane Voir le message
    j'ai obtenu mon premier point lors de cette discussion.
    Du coup j’ai voté deux fois pour vous : une fois pour votre premier message, dans lequel vous exposez votre problème avec clarté, dans un français impeccable (ce qui devient de plus en plus rare ), et une fois pour votre dernier message, dans lequel vous faites un bilan sans fioritures et pour lequel on ne trouve rien à redire.


    On y arrivera...
    (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. #13
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,

    Encore une fois, merci !

    Avec le très peu d'expérience professionnelle que j'ai, le projet me faisait peur au début. Mais maintenant, je me sens suffisamment soutenu pour y arriver.

    Il y a une petite rectification à faire concernant le précédent diagramme. Un corps peut déterminer plusieurs cadres.

    Nom : administration7.jpg
Affichages : 4279
Taille : 45,1 Ko

    J'espère que le diagramme tient toujours.

    Revenons un peu sur la classification. Nous avons dit plus haut qu'un corps est divisé en classes qui comprennent elles-mêmes un certain nombre d’échelons. Ce qui nous valu la représentation suivante :

    Nom : administration8.jpg
Affichages : 2030
Taille : 22,4 Ko

    La plupart des corps sont organisés suivant ce modèle. Cependant, certains d'entre eux présentent des spécificités que l'on peut étudier au cas par cas.

    Cas 1 :

    Corps Fonctions Classes Groupes Échelons

    Dans le cas 1, il existe deux autres classes FONCTION et GROUPE.

    Nom : administration13.jpg
Affichages : 2041
Taille : 32,4 Ko

    Cas 2 :

    Corps Collège Fonctions Classes Groupes Échelons

    En plus des classes FONCTION et GROUPE le cas 2 dispose d'une troisième classe COLLEGE.

    Nom : administration14.jpg
Affichages : 2056
Taille : 34,6 Ko

    Ce que l'on peut résumer dans le diagramme suivant :

    Nom : administration15.jpg
Affichages : 6060
Taille : 46,8 Ko

    Ce modèle est-il correct ?

    Merci !

  14. #14
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut Contraintes de chemin et compagnie
    Bonsoir mossane,


    Citation Envoyé par mossane Voir le message
    Il y a une petite rectification à faire concernant le précédent diagramme. Un corps peut déterminer plusieurs cadres.
    Reprenons donc votre diagramme :



    Pour voir quelles anomalies pourraient se glisser, il est nécessaire de prendre des exemples concrets comme on l’a déjà fait, il n’y a rien de tel...


    Allons-y, avec un exemple conforme au diagramme, minimal mais suffisant pour secouer celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CADRE 
    
    CadreId    
    -------
    ca1
    ca2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TEXTE_CADRE
    
    TexteId    CadreId
    -------      
    t1         ca2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CORPS
    
    CorpsId    CorpsTypeId
    -------                
    co1        coty1
    co2        coty2
    Cette fois-ci, l’association entre CADRE et CORPS est du type plusieurs à plusieurs, elle fera donc l’objet d’une table au niveau SQL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CADRE_CORPS 
    
    CadreId    CorpsId
    -------    -------
    ca1        co1
    Même principe pour l’association entre TEXTE_CADRE et CORPS :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TEXTE_CADRE_CORPS
    
    TexteId    CadreId    CorpsId
    -------    -------    -------
    t1         ca1        co2

    C’est la table CADRE_CORPS qui fait foi en matière d’association de cadres et de corps, et en l’occurrence le corps <co1> est rattaché au cadre <ca1> et à lui seul. Mais patatras ! La table TEXTE_CADRE_CORPS contient la paire <ca1, co2>, valide du point de vue du modèle, mais illégale parce qu’elle n’est n’apparaît pas comme élément de la table CADRE_CORPS. It's a nasty situation, isn’t it?

    Puisque la table CADRE_CORPS est en fait une référence pour la table TEXTE_CADRE_CORPS, appelons un chat un chat (et Rollet un fripon), modélisons ainsi :




    Cette fois-ci, la paire <ca1, co2> n’est plus valide pour la table TEXTE_CADRE_CORPS (viol d’intégrité référentielle). Pour être conforme, le système devient par exemple le suivant :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CADRE 
    
    CadreId    
    -------
    ca1
    ca2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TEXTE_CADRE
    
    TexteId    CadreId
    -------      
    t1         ca2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CORPS
    
    CorpsId    CorpsTypeId
    -------                
    co1        coty1
    co2        coty2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CADRE_CORPS 
    
    CadreId    CorpsId
    -------    -------
    ca1        co1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    TEXTE_CADRE_CORPS
    
    TexteId    CadreId    CorpsId
    -------    -------    -------
    t1         ca1        co1

    Pour autant, a-t-on suffisamment bétonné ?

    J’avais écrit :
    Citation Envoyé par fsmrel Voir le message
    On peut naviguer de deux façons en partant de TEXTE_CADRE pour atteindre CADRE : soit en empruntant le chemin allant directement de TEXTE_CADRE à CADRE, soit en empruntant le chemin passant par CORPS, mais alors rien ne garantit que le cadre qu’on atteint est celui qui est défini par TEXTE_CADRE...

    On retombe sur un problème du cheminement : si la table TEXTE_CADRE_CORPS est nécessairement conforme, en relation ave la table CADRE_CORPS, cette fois-ci, en « remontant » vers TEXTE_CADRE (association par la colonne TexteId), on a une contradiction en ce qui concerne le cadre : selon la table TEXTE_CADRE, le texte <t1> est associé au seul cadre <ca2>, alors que selon la table TEXTE_CADRE_CORPS, le texte <t1> est associé au cadre <ca1> (il pourrait être associé à <ca2>, mais ici il ne l’est pas).

    Ainsi, on n’a pas suffisamment bétonné, mais conceptuellement, on ne peut pas faire plus. En conséquence, il faudra poursuivre le bétonnage au niveau SQL.

    Logiquement, ça sera au moyen de triggers (tant que les SGBD SQL ne proposeront pas l’instruction CREATE ASSERTION), mais je vous propose une alternative, car les triggers sont toujours délicats à manier et parfois pris en défaut du fait de règles de gestion particulièrement subtiles (en 20 ans de triggers, j’ai eu l’occasion de le constater...)

    Examinons le MLD dérivé du diagramme pour la partie qui nous intéresse :




    Et le code SQL généré avec les inserts qui vont bien :


    TABLE CORPS_TYPE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE CORPS_TYPE 
    (
       CorpsTypeId        INT NOT NULL,
       CorpsTypeLibelle   VARCHAR(64) NOT NULL,
       CONSTRAINT CORPS_TYPE_PK PRIMARY KEY (CorpsTypeId)
    ) ;
     
    INSERT INTO CORPS_TYPE (CorpsTypeId, CorpsTypeLibelle) VALUES (1, 'corps type 1') ;
    INSERT INTO CORPS_TYPE (CorpsTypeId, CorpsTypeLibelle) VALUES (2, 'corps type 2') ;
     
    SELECT *, '' AS  '<= CORPS_TYPE' FROM CORPS_TYPE ;

    TABLE HIERARCHIE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE HIERARCHIE 
    (
       HierarchieId         INT NOT NULL,
       HierarchieLibelle    VARCHAR(64) NOT NULL,
       HierarchieOrdre      VARCHAR(64) NOT NULL,
       CONSTRAINT HIERARCHIE_PK PRIMARY KEY (HierarchieId)
    ) ;
     
    INSERT INTO HIERARCHIE (HierarchieId, HierarchieLibelle, HierarchieOrdre) VALUES (1, 'hiérarchie 1', 'ordre 1') ;
     
    SELECT *, '' AS  '<= HIERARCHIE' FROM HIERARCHIE ;

    TABLE CORPS
    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
    CREATE TABLE CORPS 
    (
       CorpsId              INT NOT NULL,
       HierarchieId         INT NOT NULL,
       CorpsTypeId          INT NOT NULL,
       CorpsCode            CHAR(8) NOT NULL,
       CorpsLibelle         VARCHAR(64) NOT NULL,
       CONSTRAINT CORPS_PK PRIMARY KEY (CorpsId),
       CONSTRAINT CORPS_AK UNIQUE (CorpsCode),
       CONSTRAINT CORPS_CORPS_TYPE_FK FOREIGN KEY (CorpsTypeId)
          REFERENCES CORPS_TYPE (CorpsTypeId),
       CONSTRAINT CORPS_HIERARCHIE_FK FOREIGN KEY (HierarchieId)
          REFERENCES HIERARCHIE (HierarchieId)
    ) ;
     
    INSERT INTO CORPS (CorpsId, HierarchieId, CorpsTypeId, CorpsCode, CorpsLibelle) VALUES (1, 1, 1, 'co1', 'corps 1') ;
     
    SELECT *, '' AS  '<= CORPS' FROM CORPS ;

    TABLE CADRE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE CADRE 
    (
       CadreId              INT NOT NULL,
       CadreCode            VARCHAR(8) NOT NULL,
       CadreLibelle         VARCHAR(64) NOT NULL,
       CONSTRAINT CADRE_PK PRIMARY KEY (CadreId)
    ) ;
     
    INSERT INTO CADRE (CadreId, CadreCode, CadreLibelle) VALUES (1, 'ca1', 'cadre 1') ;
    INSERT INTO CADRE (CadreId, CadreCode, CadreLibelle) VALUES (2, 'ca2', 'cadre 2') ;
     
    SELECT *, '' AS  '<= CADRE' FROM CADRE ;

    TABLE CADRE_CORPS
    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
    CREATE TABLE CADRE_CORPS 
    (
       CadreId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT CADRE_CORPS_PK PRIMARY KEY (CadreId, CorpsId),
       CONSTRAINT CADRE_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
          REFERENCES CORPS (CorpsId),
       CONSTRAINT CADRE_CORPS_CADRE_FK FOREIGN KEY (CadreId)
          REFERENCES CADRE (CadreId)
    ) ;
     
    INSERT INTO CADRE_CORPS (CadreId, CorpsId) VALUES (1, 1) ;
     
    SELECT *, '' AS  '<= CADRE_CORPS' FROM CADRE_CORPS ;

    TABLE TEXTE
    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
    CREATE TABLE TEXTE 
    (
       TexteId              INT NOT NULL,
       TexteNumero          VARCHAR(4) NOT NULL,
       TexteDate            DATE NOT NULL,
       TexteType            VARCHAR(8) NOT NULL,
       Observation          VARCHAR(64) NOT NULL,
       CONSTRAINT TEXTE_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_AK UNIQUE (TexteNumero)
    ) ;
     
    INSERT INTO TEXTE (TexteId, TexteNumero, TexteDate, TexteType, Observation) VALUES (1, 'A001', '2014-08-03', 'cadre', '') ;
    INSERT INTO TEXTE (TexteId, TexteNumero, TexteDate, TexteType, Observation) VALUES (2, 'B005', '2014-10-13', 'cadre', '') ;
     
    SELECT *, '' AS  '<= TEXTE' FROM TEXTE ;

    TEXTE_CADRE
    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
    CREATE TABLE TEXTE_CADRE 
    (
       TexteId              INT NOT NULL,
       CadreId              INT NOT NULL,
       CONSTRAINT TEXTE_CADRE_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_CADRE_CADRE_FK FOREIGN KEY (CadreId)
          REFERENCES CADRE (CadreId),
       CONSTRAINT TEXTE_CADRE_TEXTE_FK FOREIGN KEY (TexteId)
          REFERENCES TEXTE (TexteId)
    ) ;
     
    INSERT INTO TEXTE_CADRE (TexteId, CadreId) VALUES (1, 2) ;
     
    SELECT *, '' AS  '<= TEXTE_CADRE' FROM TEXTE_CADRE ;

    TABLE TEXTE_CADRE_CORPS
    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
    CREATE TABLE TEXTE_CADRE_CORPS 
    (
       TexteId              INT NOT NULL,
       CadreId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT TEXTE_CADRE_CORPS_PK PRIMARY KEY (TexteId, CadreId, CorpsId),
       CONSTRAINT TEXTE_CADRE_CORPS_TEXTE_CADRE_FK FOREIGN KEY (TexteId)
          REFERENCES TEXTE_CADRE (TexteId),
       CONSTRAINT TEXTE_CADRE_CORPS_CADRE_CORPS_FK FOREIGN KEY (CadreId, CorpsId)
          REFERENCES CADRE_CORPS (CadreId, CorpsId)
    ) ;
     
    INSERT INTO TEXTE_CADRE_CORPS (TexteId, CadreId, CorpsId) VALUES (1, 1, 1) ;
     
    SELECT *, '' AS  '<= TEXTE_CADRE_CORPS' FROM TEXTE_CADRE_CORPS ;



    Pour bétonner, il faudrait que la paire {TexteId, CadreId} de la table TEXTE_CADRE_CORPS fasse référence à la paire {TexteId, CadreId} de la table TEXTE_CADRE c'est-à-dire qu’on établisse une contrainte d’inclusion : y a du trigger en vue, mais pour éviter ça, je suggère une vieille ruse, consistant à déclarer une surclé {TexteId, CadreId} pour la table TEXTE_CADRE (contrainte TEXTE_CADRE_SK), à la quelle fera référence (au motif d’intégrité référentielle) la paire {TexteId, CadreId} de la table TEXTE_CADRE_CORPS :

    TABLE TEXTE_CADRE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE TEXTE_CADRE 
    (
       TexteId              INT NOT NULL,
       CadreId              INT NOT NULL,
       CONSTRAINT TEXTE_CADRE_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_CADRE_SK UNIQUE (TexteId, CadreId),
       CONSTRAINT TEXTE_CADRE_CADRE_FK FOREIGN KEY (CadreId)
          REFERENCES CADRE (CadreId),
       CONSTRAINT TEXTE_CADRE_TEXTE_FK FOREIGN KEY (TexteId)
          REFERENCES TEXTE (TexteId)
    ) ;

    TABLE TEXTE_CADRE_CORPS
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE TEXTE_CADRE_CORPS 
    (
       TexteId              INT NOT NULL,
       CadreId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT TEXTE_CADRE_CORPS_PK PRIMARY KEY (TexteId, CadreId, CorpsId),
       CONSTRAINT TEXTE_CADRE_CORPS_TEXTE_CADRE_FK FOREIGN KEY (TexteId, CadreId)
          REFERENCES TEXTE_CADRE (TexteId, CadreId),
       CONSTRAINT TEXTE_CADRE_CORPS_CADRE_CORPS_FK FOREIGN KEY (CadreId, CorpsId)
          REFERENCES CADRE_CORPS (CadreId, CorpsId)
    ) ;


    Maintenant, il faut que je souffle un peu, je traiterai de la 2e partie demain (collèges, groupes, fonctions, etc.) Si vous avez des remarques et des questions...
    (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. #15
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Au sujet des nouveaux arrivants (COLLEGE et Cie), reprenons votre diagramme :




    On y voit qu’une fonction fait nécessairement référence à un collège ainsi qu’à un corps : pourtant, vous avez précisé (votre cas 1) qu’une fonction est rattachée soit à un corps, soit à une classe. La représentation suivante serait plus conforme :





    Vu du modèle, on peut avoir la situation suivante, où le mickey « !! » a le sens de « sans objet » (inapplicable), conséquence du « soit, soit » :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CORPS
    
    CorpsId    CorpsCode    CorpsLibelle
    -------
    
    co1        COR26G       libelle de co1 
    co2        COR07A       libelle de co2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    COLLEGE 
    
    CollegeId    CollegeCode    CollegeLibelle    CorpsId
    ---------
    
    cg1          G75JK          libelle de cg1    co1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    FONCTION
    
    FonctionId    FonctionCode    FonctionLibelle    CollegeId    CorpsId
    ----------
    fn1           XYZ14           libelle de fn1     cg1          !! 
    fn2           DTM02           libelle de fn2     !!           co2 
    fn3           MUT45           libelle de fn3     cg1          co1
    fn4           FFF74           libelle de fn4     cg1          co2

    Dans le cas de la fonction <fn1>, le corps de la fonction est celui du collège, il s’agit donc de <co1>. Pas de problème.

    Dans le cas de la fonction <fn2>, celle-ci est directement rattachée au corps <co2>. Pas de problème non plus.

    Dans le cas de la fonction <fn3>, on retrouve ce que vous avez en fait modélisé, où il est sous-entendu (appelons ça la règle R314) que si la fonction fait référence à un collège, elle doit aussi faire référence au corps auquel est rattaché ce collège : pour faire respecter cette règle, on subodore qu’il faudra sortir l’artillerie des triggers...

    Dans le cas de la fonction <fn4>, on viole la règle R314, mais selon le diagramme elle est bien légale : ça confirme que pour interdire cette situation il y aura du trigger sur le pont...

    Et, last but not least ! Le hors-la-loi, le bonhomme NULL a fait son entrée en scène, symbolisé ici par « !! ». Je ne vais pas m’étendre sur la nocivité du bonhomme, je l’ai fait dans de nombreuses discussions, en tout cas il faut à tout prix lui interdire l’accès à la base de données.


    Dans ces conditions, je propose de faire évoluer la modélisation ainsi :

    Une fonction concerne soit un corps, soit un collège, ce qui peut faire l’objet d’une spécialisation :




    En conséquence de quoi, d’une part le bonhomme NULL ne pourra pas se manifester, d’autre part le triplet <fn4, cg1, co2> ne pourra pas venir ficher la patouille. Suite à la modification du diagramme on passe à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CORPS
    
    CorpsId    CorpsCode    CorpsLibelle
    -------
    
    co1        COR26G       libellé de co1 
    co2        COR07A       libellé de co2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    COLLEGE 
    
    CollegeId    CollegeCode    CollegeLibelle    CorpsId
    ---------
    
    cg1          G75JK          libellé de cg1    co1  
    cg2          G75JK          libellé de cg2    co2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    FONCTION
    --------
    
    FonctionId    FonctionCode    FonctionLibelle    
    ----------
    fn1           XYZ14           libellé de fn1     
    fn2           DTM02           libellé de fn2      
    fn3           MUT45           libellé de fn3     
    fn4           FFF74           libellé de fn4

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    FONCTION_CORPS
    
    FonctionId    CorpsId    
    ----------
    fn2           co2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    FONCTION_COLLEGE
    
    FonctionId    CollegeId    
    ----------
    fn2           cg1
    fn3           cg1
    fn4           cg1

    Code SQL correspondant :

    TABLE CORPS
    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
     CREATE TABLE CORPS 
    (
       CorpsId              INT NOT NULL,
       HierarchieId         INT NOT NULL,
       CorpsTypeId          INT NOT NULL,
       CorpsCode            CHAR(8) NOT NULL,
       CorpsLibelle         VARCHAR(64) NOT NULL,
       CONSTRAINT CORPS_PK PRIMARY KEY (CorpsId),
       CONSTRAINT CORPS_AK UNIQUE (CorpsCode),
       CONSTRAINT CORPS_CORPS_TYPE_FK FOREIGN KEY (CorpsTypeId)
          REFERENCES CORPS_TYPE (CorpsTypeId),
       CONSTRAINT CORPS_HIERARCHIE_FK FOREIGN KEY (HierarchieId)
          REFERENCES HIERARCHIE (HierarchieId)
    ) ;
     
    INSERT INTO CORPS (CorpsId, HierarchieId, CorpsTypeId, CorpsCode, CorpsLibelle) VALUES (1, 1, 1, 'co1', 'corps 1') ;
    INSERT INTO CORPS (CorpsId, HierarchieId, CorpsTypeId, CorpsCode, CorpsLibelle) VALUES (2, 1, 1, 'co2', 'corps 2') ;
     
    SELECT *, '' AS  '<= CORPS' FROM CORPS ;


    TABLE FONCTION
    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
    CREATE TABLE FONCTION 
    (
       FonctionId              INT NOT NULL,
       FonctionsCode           CHAR(8) NOT NULL,
       FonctionLibelle         VARCHAR(64) NOT NULL,
       CONSTRAINT FONCTION_PK PRIMARY KEY (FonctionId),
       CONSTRAINT FONCTION_AK UNIQUE (FonctionsCode)
    ) ;
     
    INSERT INTO FONCTION (FonctionId, FonctionsCode, FonctionLibelle) VALUES (1, 'fn1', 'fonction 1') ;
    INSERT INTO FONCTION (FonctionId, FonctionsCode, FonctionLibelle) VALUES (2, 'fn2', 'fonction 2') ;
    INSERT INTO FONCTION (FonctionId, FonctionsCode, FonctionLibelle) VALUES (3, 'fn3', 'fonction 3') ;
    INSERT INTO FONCTION (FonctionId, FonctionsCode, FonctionLibelle) VALUES (4, 'fn4', 'fonction 4') ;
    INSERT INTO FONCTION (FonctionId, FonctionsCode, FonctionLibelle) VALUES (5, 'fn5', 'fonction 5') ;
     
    SELECT *, '' AS  '<= FONCTION' FROM FONCTION ;

    TABLE COLLEGE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE COLLEGE 
    (
       CollegeId              INT NOT NULL,
       CollegeCode            CHAR(8) NOT NULL,
       CollegeLibelle         VARCHAR(64) NOT NULL, 
       CONSTRAINT COLLEGE_PK PRIMARY KEY (CollegeId),
       CONSTRAINT COLLEGE_AK UNIQUE (CollegeId)
    ) ;
     
    INSERT INTO COLLEGE (CollegeId, CollegeCode, CollegeLibelle) VALUES (1, 'cg1', 'collège 1') ;
     
    SELECT *, '' AS  '<= COLLEGE' FROM COLLEGE ;

    TABLE FONCTION_CORPS
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TABLE FONCTION_CORPS 
    (
       FonctionId              INT NOT NULL,
       CorpsId                 INT NOT NULL,
       CONSTRAINT FONCTION_CORPS PRIMARY KEY (FonctionId),
       CONSTRAINT FONCTION_CORPS_FONCTION_FK FOREIGN KEY (FonctionId)
           REFERENCES FONCTION (FonctionId) ON DELETE CASCADE,
       CONSTRAINT FONCTION_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
           REFERENCES CORPS (CorpsId)    
    ) ;
    INSERT INTO FONCTION_CORPS (FonctionId, CorpsId) VALUES (2, 2) ;
     
    SELECT *, '' AS  '<= FONCTION_CORPS' FROM FONCTION_CORPS ;

    TABLE FONCTION_COLLEGE
    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
    CREATE TABLE FONCTION_COLLEGE
    (
       FonctionId              INT NOT NULL,
       CollegeId               INT NOT NULL,
       CONSTRAINT FONCTION_COLLEGE PRIMARY KEY (FonctionId),
       CONSTRAINT FONCTION_COLLEGE_FONCTION_FK FOREIGN KEY (FonctionId)
           REFERENCES FONCTION (FonctionId) ON DELETE CASCADE,
       CONSTRAINT FONCTION_COLLEGE_COLLEGE_FK FOREIGN KEY (CollegeId)
           REFERENCES COLLEGE (CollegeId)  
    ) ;
     
    INSERT INTO FONCTION_COLLEGE (FonctionId, CollegeId) VALUES (1, 1) ;
    INSERT INTO FONCTION_COLLEGE (FonctionId, CollegeId) VALUES (3, 1) ;
    INSERT INTO FONCTION_COLLEGE (FonctionId, CollegeId) VALUES (4, 1) ;
     
    SELECT *, '' AS  '<= FONCTION_COLLEGE' FROM FONCTION_COLLEGE ;


    Au niveau SQL, il faudra quand même prévoir un trigger pour assurer la contrainte (implicite dans le diagramme) selon laquelle une fonction ne peut pas être à la fois une fonction référençant à la fois un corps et un collège (ceci vaut du reste à chaque fois qu’on a mis en œuvre la spécialisation).

    Exemple avec MySQL :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TRIGGER FONCTION_CORPS_TR BEFORE INSERT ON FONCTION_CORPS
    FOR EACH ROW 
    BEGIN
        SET @N = (
                  SELECT COUNT(*) 
                  FROM   FONCTION_COLLEGE 
                  WHERE FonctionId = NEW.FonctionId
                  ) ;
        IF  @N > 0 THEN
            SET @T = CONCAT ('Ajout d’une fonction de type corps : une fonction de type collège existe déjà pour l’attribut FonctionId égal à ', NEW.FonctionId) ; 
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T ;
        END IF ; 
    END ;


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TRIGGER FONCTION_COLLEGE_TR BEFORE INSERT ON FONCTION_COLLEGE
    FOR EACH ROW 
    BEGIN
        SET @N = (
                  SELECT COUNT(*) 
                  FROM   FONCTION_CORPS 
                  WHERE FonctionId = NEW.FonctionId
                 ) ;
        IF  @N > 0 THEN
            SET @T = CONCAT ('Ajout d’une fonction de type collège : une fonction de type corps existe déjà pour l’attribut FonctionId égal à ', NEW.FonctionId) ;
            SIGNAL   SQLSTATE '45001' SET MESSAGE_TEXT = @T ;
       END IF ; 
    END ;


    Ce qui vaut pour les fonctions vaut bien entendu pour les échelons, etc.

    Courage !
    (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.

  16. #16
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,

    J'ai encore accusé du retard et je m'en excuse. Je voulais m'assurer que j'ai bien compris vos deux derniers messages. J'ai des remarques à faire à propos de l'avant-dernier (message).

    Reprenons encore le diagramme.

    Nom : administration7.jpg
Affichages : 2063
Taille : 45,1 Ko

    Citation Envoyé par fsmrel
    La table TEXTE_CADRE_CORPS contient la paire <ca1, co2>, valide du point de vue du modèle, mais illégale parce qu’elle n’est n’apparaît pas comme élément de la table CADRE_CORPS.
    La table TEXTE_CADRE_CORPS résulte de l'association entre TEXTE_CADRE et CORPS. CADRE n'étant pas directement liée à cette association, doit-on retrouver l'attribut CadreId de CADRE dans la table TEXTE_CADRE_CORPS ?

    Je trouve intéressant, très intéressant le fait que vous ayez maintenu la table TEXTE au niveau SQL. Je me disais qu'elle allait disparaître à ce niveau au profit des tables spécialisées TEXTE_CADRE, TEXTE_CORPS_TYPE et TEXTE_CORPS chacune d'elles héritant de tous ses attributs.

    Citation Envoyé par fsmrel
    Maintenant, il faut que je souffle un peu, je traiterai de la 2e partie demain (collèges, groupes, fonctions, etc.)
    C'est normal. Vous avez abattu un travail énorme et je vous en remercie.

    Je termine la modélisation que vous avez entamée dans votre dernier message et je reviens vers vous sous peu.

    Merci !

  17. #17
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Citation Envoyé par mossane Voir le message
    J'ai encore accusé du retard et je m'en excuse.
    Prenez votre temps, ne foncez pas en aveugle. Vous pouvez tâtonner pendant un mois à chercher l’interrupteur qui va permettre d’éclairer la pièce : une fois que c’est fait, c’est tout bon et on peut passer à la pièce suivante...



    Citation Envoyé par mossane Voir le message
    La table TEXTE_CADRE_CORPS résulte de l'association entre TEXTE_CADRE et CORPS. CADRE n'étant pas directement liée à cette association, doit-on retrouver l'attribut CadreId de CADRE dans la table TEXTE_CADRE_CORPS ?

    Examinons le diagramme :



    Sa dérivation donne lieu à la structure tabulaire suivante :



    Où l’attribut CadreId ne fait pas partie de l’en-tête de la table TEXTE_CADRE_CORPS. Afin d’éviter que soient introduites des incohérences dans la base de données, il faut arriver à faire figurer CadreId dans l’en-tête de cette table, d’où la diagramme que j’avais proposé :



    Et la structure dérivée :



    Selon ce diagramme, seulement si la paire {CadreId, CorpsId} de l’en-tête de la table CADRE_CORPS contient la valeur <a, b> alors la paire {CadreId, CorpsId} de l’en-tête de la table TEXTE_CADRE_CORPS peut aussi contenir cette valeur.



    Citation Envoyé par mossane Voir le message
    Je trouve intéressant, très intéressant le fait que vous ayez maintenu la table TEXTE au niveau SQL. Je me disais qu'elle allait disparaître à ce niveau au profit des tables spécialisées TEXTE_CADRE, TEXTE_CORPS_TYPE et TEXTE_CORPS chacune d'elles héritant de tous ses attributs.
    Au niveau tabulaire, on a le choix ! Cela dit, prévoir un trigger pour garantir la règle : un texte est d’un type et d’un seul (texte cadre, texte corps, texte corps type).


    Prenez tout votre temps...
    (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.

  18. #18
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonsoir fsmrel,

    Citation Envoyé par fsmrel Voir le message
    Prenez tout votre temps...
    D'accord, je vais prendre mon temps et surtout essayer de comprendre le diagramme dans ses moindres détails.

    Justement, il y a une multiplicité qui me préoccupe encore.

    De cette représentation :

    Nom : mossane_corps_cadre_texte_cadre.png
Affichages : 2053
Taille : 47,5 Ko

    On est passé à celle-ci :

    Nom : mossane_DC_texte_cadre_corps_v2_dc_beton.png
Affichages : 2043
Taille : 5,7 Ko

    Dans le premier schéma, je vois qu'un corps est associé au moins à un cadre (multiplicité 1..*) . Ce qui est bien le cas dans notre contexte. Dans le second, il me semble qu'un corps n'est plus systématiquement rattaché à un cadre (multiplicité 0..* du coté de CADRE_CORPS).

    Cependant, l'implémentation au niveau SQL, impose qu'un corps se réfère à un cadre (contrainte NOT NULL sur CorpsId).

    Citation Envoyé par fsmrel
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE CADRE_CORPS 
    (
       CadreId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT CADRE_CORPS_PK PRIMARY KEY (CadreId, CorpsId),
       CONSTRAINT CADRE_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
          REFERENCES CORPS (CorpsId),
       CONSTRAINT CADRE_CORPS_CADRE_FK FOREIGN KEY (CadreId)
          REFERENCES CADRE (CadreId)
    ) ;
    Dans ce cas, peut-on faire évoluer la multiplicité de 0..* vers 1..* ?

    Pour m'assurer que j'ai bien compris, je vais traiter de l'autre partie du diagramme.

    Nom : administration16.jpg
Affichages : 2270
Taille : 31,8 Ko

    Dans le diagramme ci-dessus, il est possible qu'un corps co fasse référence à un texte corps type tct qui détermine un corps type ct dont il (co) ne fait pas partie. Alors, pour empêcher cette incohérence, faisons évoluer le schéma vers la représentation suivante comme vous l'avez fait dans l'autre partie.

    Nom : administration17.jpg
Affichages : 2216
Taille : 38,5 Ko

    Ce qui nous donne la structure dérivée suivante :

    Nom : administration18.jpg
Affichages : 2161
Taille : 48,2 Ko

    Cette structure dérivée ne respecte peut-être pas la norme. Mais pour le moment, c'est ce que j'ai pu faire de mieux avec mon logiciel de modélisation.

    Passons à l'implémentation au niveau SQL.

    Table CORPS_TYPE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE CORPS_TYPE 
    (
       CorpsTypeId        INT NOT NULL,
       CorpsTypeLibelle   VARCHAR(64) NOT NULL,
       CONSTRAINT CORPS_TYPE_PK PRIMARY KEY (CorpsTypeId)
    ) ;

    Table CORPS
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     CREATE TABLE CORPS 
    (
       CorpsId              INT NOT NULL,
       CorpsCode            CHAR(8) NOT NULL,
       CorpsLibelle         VARCHAR(64) NOT NULL,
       CONSTRAINT CORPS_PK PRIMARY KEY (CorpsId),
       CONSTRAINT CORPS_AK UNIQUE (CorpsCode),
    ) ;

    Table TEXTE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CREATE TABLE TEXTE 
    (
       TexteId              INT NOT NULL,
       TexteTexteId       INT NULL,
       TexteNumero          VARCHAR(4) NOT NULL,
       TexteDate            DATE NOT NULL,
       TexteType            VARCHAR(8) NOT NULL,
       Observation          VARCHAR(64) NOT NULL,
       CONSTRAINT TEXTE_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_AK UNIQUE (TexteNumero),
       CONSTRAINT TEXTE_TEXTE_FK FOREIGN KEY (TexteTexteId)
          REFERENCES TEXTE (TexteId)
    ) ;

    Table CORPS_TYPE_CORPS
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE CORPS_TYPE_CORPS 
    (
       CorpsTypeId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT CORPS_TYPE_CORPS_PK PRIMARY KEY (CorpsTypeId, CorpsId)
       CONSTRAINT CORPS_TYPE_CORPS_CORPS_TYPE_FK FOREIGN KEY (CorpsTypeId)
          REFERENCES CORPS_TYPE (CorpsTypeId),
       CONSTRAINT CORPS_TYPE_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
          REFERENCES CORPS (CorpsId)
    ) ;

    Table TEXTE_CORPS
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE TEXTE_CORPS 
    (
       TexteId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT TEXTE_CORPS_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
          REFERENCES CORPS (CorpsId),
       CONSTRAINT TEXTE_CORPS_TEXTE_FK FOREIGN KEY (TexteId)
          REFERENCES TEXTE (TexteId)
    ) ;

    Table TEXTE_CORPS_TYPE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE TEXTE_CORPS_TYPE
    (
       TexteId              INT NOT NULL,
       CorpsTypeId              INT NOT NULL,
       CONSTRAINT TEXTE_CORPS_TYPE_PK PRIMARY KEY (TexteId),
       CONSTRAINT TEXTE_CORPS_TYPE_SK UNIQUE (TexteId, CorpsTypeId),
       CONSTRAINT TEXTE_CORPS_TYPE_CORPS_TYPE_FK FOREIGN KEY (CorpsTypeId)
          REFERENCES CORPS_TYPE (CorpsTypeId),
       CONSTRAINT TEXTE_CORPS_TYPE_TEXTE_FK FOREIGN KEY (TexteId)
          REFERENCES TEXTE (TexteId)
    ) ;

    Table CORPS_TYPE_CORPS_TEXTE
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE CORPS_TYPE_CORPS_TEXTE
    (
       TexteId              INT NOT NULL,
       CorpsTypeId              INT NOT NULL,
       CorpsId              INT NOT NULL,
       CONSTRAINT CORPS_TYPE_CORPS_TEXTE_PK PRIMARY KEY (TexteId, CorpsTypeId, CorpsId),
       CONSTRAINT CORPS_TYPE_CORPS_TEXTE_TEXTE_CORPS_TYPE_FK FOREIGN KEY (TexteId, CorpsTypeId)
          REFERENCES TEXTE_CORPS_TYPE (TexteId, CorpsTypeId),
       CONSTRAINT CORPS_TYPE_CORPS_TEXTE_CORPS_TYPE_CORPS_FK FOREIGN KEY (CorspTypeId, CorpsId)
          REFERENCES CORPS_TYPE_CORPS (CorpsTypeId, CorpsId)
    ) ;

    Est-ce bien cela ?

    Merci !

  19. #19
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    7 965
    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 : 7 965
    Points : 30 774
    Points
    30 774
    Billets dans le blog
    16
    Par défaut
    Bonsoir mossane,


    Citation Envoyé par mossane Voir le message
    Dans le premier schéma, je vois qu'un corps est associé au moins à un cadre (multiplicité 1..*) . Ce qui est bien le cas dans notre contexte. Dans le second, il me semble qu'un corps n'est plus systématiquement rattaché à un cadre (multiplicité 0..* du coté de CADRE_CORPS).
    Je n’ai pas été très vigilant, conservons la multiplicité 1..*.



    Citation Envoyé par mossane Voir le message
    Cependant, l'implémentation au niveau SQL, impose qu'un corps se réfère à un cadre (contrainte NOT NULL sur CorpsId).
    Citation Envoyé par fsmrel
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE CADRE_CORPS 
    (
    CadreId INT NOT NULL,
    CorpsId INT NOT NULL,
    CONSTRAINT CADRE_CORPS_PK PRIMARY KEY (CadreId, CorpsId),
    CONSTRAINT CADRE_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
    REFERENCES CORPS (CorpsId),
    CONSTRAINT CADRE_CORPS_CADRE_FK FOREIGN KEY (CadreId)
    REFERENCES CADRE (CadreId)
    ) ;
    Dans ce cas, peut-on faire évoluer la multiplicité de 0..* vers 1..* ?
    La contrainte NOT NULL affectée à CorpsId dit seulement que cet attribut a nécessairement une valeur, et de son côté la contrainte CADRE_CORPS_CORPS_FK signifie que la valeur prise par l’attribut CorpsId doit être une valeur existant dans la table CORPS, tout comme la valeur prise par l’attribut CadreId doit être une valeur existant dans la table CADRE. En revanche, rien ne dit qu’un corps fait nécessairement référence à un cadre. En réalité, avec SQL on ne sait pas formellement déclarer une contrainte garantissant la multiplicité 1..*, sinon en passant par l’instruction CREATE ASSERTION, décrite par la norme, mais non proposée à ce jour par les SGBD SQL.

    Pour le moment, seuls les langages basés sur Tutorial D (voyez Databases, Types, and the Relational Model, The Third Manifesto) permettent de garantir formellement les multiplicités 1..* : en plus des contraintes référentielles (qui ressemblent à celles de SQL), on déclare facilement des contraintes ad-hoc :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CONSTRAINT RG01 CADRE  {CadreId}  ⊆  CADRE_CORPS  {CadreId} ;
    CONSTRAINT RG02 CORPS  {CorpsId} ⊆  CADRE_CORPS   {CorpsId} ;

    Ainsi, pour créer le cadre 7, le corps 9 et les associer :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT CADRE RELATION {TUPLE  {CadreId 7, CadreCode 'ca7', CadreLibelle 'cadre 7', ...}} ,
    INSERT CORPS RELATION {TUPLE  {CorpsId 9, CorpsCode 'co9', CorpsLibelle 'corps 9', ...}} ,
    INSERT CADRE_CORPS RELATION {TUPLE   CadreId 7, CorpsId 9}} ;

    Il y a une subtilité : notez soigneusement que les deux premiers INSERT sont suivis par une virgule, tandis que le troisième est suivi par un point-virgule : le SGBD ne déclenchera les contrôles d’intégrité qu’une fois détecté le point-virgule.

    Si on n’avait utilisé que des points-virgules :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     INSERT CADRE RELATION {TUPLE  {CadreId 7, CadreCode 'ca7', CadreLibelle 'cadre 7', ...}} ;
    INSERT CORPS RELATION {TUPLE  {CorpsId 9, CorpsCode 'co9', CorpsLibelle 'corps 9', ...}} ;
    INSERT CADRE_CORPS RELATION {TUPLE   CadreId 7, CorpsId 9}} ;

    Alors dès le 1er INSERT le SGBD aurait déclenché une erreur, pour non respect de la contrainte RG01.

    Le problème avec SQL est que les contrôles son toujours immédiats, sauf quand, pour reprendre cet exemple, on demande à ce qu’ils soient différés, au moyen d’assertions :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE ASSERTION RG01 CHECK
        (NOT EXISTS 
            (SELECT CadreId FROM CADRE 
             EXCEPT CORRESPONDING
             SELECT CadreId FROM CADRE_CORPS
            )
        )
        INITIALLY DEFERRED DEFERRABLE ;

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE ASSERTION RG02 CHECK
        (NOT EXISTS 
            (SELECT CorpsId FROM CORPS 
             EXCEPT CORRESPONDING
             SELECT CorpsId FROM CADRE_CORPS
            )
        )
        INITIALLY DEFERRED DEFERRABLE ;

    Et pour que les INSERT ne soient pas contrôlés tout de suite :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO CADRE (CadreId, CadreCode, CadreLibelle, ...) VALUES (7, 'ca7', 'cadre 7', ...) ;
    INSERT INTO CORPS (CorpsId, CorpsCode, CorpsLibelle, ...) VALUES (9, 'co9', 'corps 9', ...) ;
    INSERT INTO CADRE_CORPS (CadreId, CorpsId) VALUES (7, 9) ;

    Eventuellement suivis d’une instruction forçant les contrôles (à défaut le SGBD attendra par exemple la fin de la transaction) :

    SET CONSTRAINT RG01 IMMEDIATE ;
    SET CONSTRAINT RG02 IMMEDIATE ;
    Le système proposé par SQL est lourd. A quand la virgule (ou une notation équivalente) pour réunir dans un seul paquet les instructions de mise à jour ? (Sachant, je le rappelle, que les SGBD SQL rechignent à proposer l’instruction CREATE ASSERTION...)



    Citation Envoyé par mossane Voir le message
    Pour m'assurer que j'ai bien compris, je vais traiter de l'autre partie du diagramme.
    Cette structure dérivée ne respecte peut-être pas la norme. Mais pour le moment, c'est ce que j'ai pu faire de mieux avec mon logiciel de modélisation.
    Le diagramme est correct. Pour les structures dérivées, c’est la grande liberté, il n’y a aucune norme !

    Pour ne pas perdre du temps à vérifier ligne par ligne le code SQL que vous avez joint, j’ai demandé à MySQL Workbench de faire le travail J’ai donc rassemblé dans un fichier texte les CREATE TABLE et les lui ai soumis pour rétro-conception.

    MWB a relevé quelques petites erreurs de syntaxe ou d’orthographe, mais rien de grave :

    Table CORPS, supprimer la virgule en fin de ligne :
    CONSTRAINT CORPS_AK UNIQUE (CorpsCode),

    Table CORPS_TYPE_CORPS, ajouter une virgule en fin de ligne :
    CONSTRAINT CORPS_TYPE_CORPS_PK PRIMARY KEY (CorpsTypeId, CorpsId)

    Table CORPS_TYPE_CORPS_TEXTE, remplacer CorspTypeId par CorpsTypeId :
    CONSTRAINT CORPS_TYPE_CORPS_TEXTE_CORPS_TYPE_CORPS_FK FOREIGN KEY (CorspTypeId, CorpsId)


    Après correction, voici ce qu’il propose :



    Il est optimiste, en plaçant des multiplicités systématiquement 1..*, mais on ne peut lui en vouloir puisqu’on ne lui a pas fourni les assertions qui vont bien (et qu’il serait bien en peine d’interpréter...) A mon avis, il aurait mieux fait d’utiliser 0..*, mais bon : la tâche n’est pas bien lourde de procéder aux aménagements. En revanche, il devrait savoir que la multiplicité 1..* portée par le lien connectant par exemple TEXTE et TEXTE CORPS est 0..1 (à la limite 1, vu son optimisme...), en effet la clé de TEXTE CORPS est le singleton {TexteId}. J’ai reporté cela comme un bug aux gens qui font MySQL Workbench, mais ils sont bien chargés par ailleurs...

    Bref, une fois aménagées les multiplicités, grâce à MySQL Workbench vous disposez d’un diagramme correct.

    Bravo pour le soin et l'intérêt que vous portez à votre travail de modélisation, je vote !
    (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.

  20. #20
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 31
    Points : 47
    Points
    47
    Par défaut
    Bonjour fsmrel,

    J'ai bien noté les remarques que vous avez formulées dans votre dernier message. Merci pour l'article sur Mysql Workbench.

    Revenons à la gestion de la classification avec les nouveaux arrivants (COLLEGE et Cie).

    Pour modéliser le fait qu'une fonction concerne soit un collège, soit un corps, vous avez proposé la spécialisation dans le diagramme suivant :

    Nom : mossane__fonctions_specialisation.png
Affichages : 2162
Taille : 5,0 Ko

    Ce qui vaut pour les fonctions vaut également pour les classes.

    Citation Envoyé par fsmrel
    Ce qui vaut pour les fonctions vaut bien entendu pour les échelons, etc.
    Nom : classification1.jpg
Affichages : 2654
Taille : 27,8 Ko

    Idem pour les groupes.

    Nom : classification2.jpg
Affichages : 2592
Taille : 28,6 Ko

    Même chose pour les échelons.

    Nom : classification3.jpg
Affichages : 2316
Taille : 30,3 Ko

    Étant limité par le nombre de fichiers à joindre par message, passons directement à la structure dérivée résultant de la fusion des quatre précédents diagrammes.

    Nom : classification5.jpg
Affichages : 3568
Taille : 77,4 Ko

    A mon avis, plusieurs triggers sont en vue.

    Citation Envoyé par fsmrel
    Au niveau SQL, il faudra quand même prévoir un trigger pour assurer la contrainte (implicite dans le diagramme) selon laquelle une fonction ne peut pas être à la fois une fonction référençant à la fois un corps et un collège (ceci vaut du reste à chaque fois qu’on a mis en œuvre la spécialisation).
    En plus des triggers résultant de la spécialisation avec les couples (ECHELON_GROUPE, ECHELON_CLASSE), (GROUPE_CLASSE, GROUPE_FONCTION), (CLASSE_FONCTION, CLASSE_CORPS), (FONCTION_COLLEGE, FONCTION_CORPS), il me semble que l'on doit prévoir d'autres triggers pour interdire la possibilité de passer par plus d'un chemin pour atteindre un corps en partant d'un échelon (et inversement).

    De ce fait, je propose les couples de triggers suivants en plus : (ECHELON_CLASSE, GROUPE_CLASSE), (GROUPE_FONCTION, CLASSE_FONCTION), (FONCTION_CORPS, CLASSE_CORPS), (CLASSE_CORPS, COLLEGE) et (FONCTION_CORPS, COLLEGE).

    Êtes-vous d'accord avec moi ?

    Autre chose. Étant donné qu'une fonction_corps par exemple appartient à un et un seul corps, peut-on remplacer les associations simples par des compositions et passer de ce code SQL :

    TABLE FONCTION_CORPS
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE FONCTION_CORPS 
    (
       FonctionId              INT NOT NULL,
       CorpsId                 INT NOT NULL,
       CONSTRAINT FONCTION_CORPS PRIMARY KEY (FonctionId),
       CONSTRAINT FONCTION_CORPS_FONCTION_FK FOREIGN KEY (FonctionId)
           REFERENCES FONCTION (FonctionId) ON DELETE CASCADE,
       CONSTRAINT FONCTION_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
           REFERENCES CORPS (CorpsId)    
    ) ;

    à celui-ci ?

    TABLE FONCTION_CORPS
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE FONCTION_CORPS 
    (
       FonctionId              INT NOT NULL,
       CorpsId                 INT NOT NULL,
       CONSTRAINT FONCTION_CORPS PRIMARY KEY (FonctionId, CorpsId),
       CONSTRAINT FONCTION_CORPS_FONCTION_FK FOREIGN KEY (FonctionId)
           REFERENCES FONCTION (FonctionId) ON DELETE CASCADE,
       CONSTRAINT FONCTION_CORPS_CORPS_FK FOREIGN KEY (CorpsId)
           REFERENCES CORPS (CorpsId) ON DELETE CASCADE   
    ) ;

    Merci !

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Réponses: 10
    Dernier message: 20/06/2017, 15h43
  2. avis pour améliorer mon diagramme de classe: gestion des sujets PFE
    Par win_ubuntu dans le forum Diagrammes de Classes
    Réponses: 0
    Dernier message: 12/08/2014, 22h35
  3. Réponses: 30
    Dernier message: 05/08/2009, 20h25
  4. [CV] Avis pour améliorer mon cv
    Par lapanne dans le forum CV
    Réponses: 7
    Dernier message: 17/10/2007, 16h04
  5. Réponses: 2
    Dernier message: 18/10/2006, 00h55

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