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

UML Discussion :

DIagramme de classe -> Base de données


Sujet :

UML

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut DIagramme de classe -> Base de données
    Bonjour, je suis actuellement en train de travailler sur un projet de gestion des archives (j'suis debutant en developpement en general). j'ai pu avec l'aide des tutos et amis et concevoir un diagramme de classe et j'arrive pas a creer une BD. aidez-moi s'il vous plaitNom : Mon diagramme de Classe.PNG
Affichages : 89567
Taille : 90,3 Ko

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

    Vous n’avez pas précisé le nom de l’AGL que vous utilisez. S’il s’agit de PowerAMC, alors pour générer la base de données, vous commencez par générer un MPD (Modèle physique des données), en réalité un MLD (modèle logique des données) :

    Le diagramme de classes étant affiché, dans la barre de menus : OUTILS > Générer un modèle physique de données.

    Une fois ce MLD généré, dans la fenêtre correspondante : dans la barre de menus : SGBD > Générer la base de données.

    Au besoin, vous pouvez préciser votre SGBD : dans la barre de menus : SGBD > Editer le SGBD courant.

    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    Oui en fait je voulais comprendre comment ca se passe je veux pas creer moi meme la base de donnée. merci

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

    Traitons donc des règles classiques du Passage à SQL.

    (1) Traduction d’une classe en table :

    La classe fait l’objet d’une table.

    Les attributs de la classe deviennent les colonnes de la table.

    Le type des attributs est parfois à renommer. Ainsi, si le type entier (INT) est le même, le type String est en général à renommer en TEXT, CHAR, VARCHAR, etc., en fonction de votre SGBD (le type le plus souvent utilisé est en l’occurrence VARCHAR).

    Les opérations sont ignorées.

    Un identifiant de classe devient une contrainte, plus précisément une clé primaire SQL (primary key) (symbolisée ci-dessous par le mickey <pk>, voyez par exemple l’attribut ServiceId). A noter qu’une clé primaire est une spécialisation de ce qu’on appelle clé candidate (dont la fonction première est de garantir la non redondance des lignes d’une table), le pendant de la clé primaire est dite clé alternative. Par exemple, si la classe SERVICE était dotée d’un attribut (naturel) ServiceCode, tel qu’il n’existe pas deux services ayant la même valeur pour cet attribut, alors la table SERVICE serait à doter d’une clé alternative {ServiceCode}.

    Exemple :


    SQL ne propose aucun graphique pour représenter les tables, seuls les AGL le font. SQL ne propose que des instructions.

    Pour les tables ci-dessus :

    CREATE TABLE SERVICE
    (
            ServiceId               INT            NOT NULL
          , ServiceNom              VARCHAR(48)    NOT NULL 
        , CONSTRAINT SERVICE_PK PRIMARY KEY (ServiceId) 
    ) ;
    CREATE TABLE ARCHIVE
    (
            ArchiveId               INT            NOT NULL
          , ArchiveNom              VARCHAR(64)    NOT NULL
          , ArchiveDate             DATE           NOT NULL
          , ArchiveTaille           INT            NOT NULL
        , CONSTRAINT ARCHIVE_PK PRIMARY KEY (ArchiveId) 
    ) ;
    

    (2) Traduction d’une association de N à 1.

    Si les AGL proposent de visualiser les liens N à 1 entre tables au moyen de ficelles plus ou moins parlantes, pour sa part SQL impose que la référence d’une table (par exemple ARCHIVE) à une autre (par exemple SERVICE) mette en jeu une contrainte dite référentielle, plus connue sous le nom (assez étrange il faut le dire) de clé étrangère (mickey <fk> ci-dessous), système qui impose d’ajouter — dans l’en-tête (liste des attributs) de la table référençante — les attributs composant la clé primaire (ou autre clé candidate) de la table référencée.


    CREATE TABLE SERVICE
    (
            ServiceId               INT            NOT NULL
          , ServiceNom              VARCHAR(48)    NOT NULL 
        , CONSTRAINT SERVICE_PK PRIMARY KEY (ServiceId) 
    ) ;
    CREATE TABLE ARCHIVE
    (
            ArchiveId               INT            NOT NULL
          , ServiceId               INT            NOT NULL
          , ArchiveNom              VARCHAR(64)    NOT NULL
          , ArchiveDate             DATE           NOT NULL
          , ArchiveTaille           INT            NOT NULL
        , CONSTRAINT ARCHIVE_PK PRIMARY KEY (ArchiveId) 
        , CONSTRAINT ARCHIVE_SERVICE_FK FOREIGN KEY (ServiceId) REFERENCES SERVICE (ServiceId)
    ) ;
    
    Notez la présence la clause « NOT NULL » : NULL est une pustule (qu’il faut éviter), plus formellement un marqueur d’attribut. Si un attribut est marqué NULL, alors il ne contient aucune valeur conforme à son type. En revanche on ne fonctionne plus alors selon le mode de la logique classique, binaire (vrai, faux), mais selon le mode de la logique ternaire (vrai, faux, n’iimporte quoi).

    Voilà pour l’instant. Il reste pas mal de cas de figures à examiner : associations N-N, classes-associations, héritage, compositions et j’en oublie, mais voyons déjà si ce qui précède vous convient. Et si cela a pu vous apporter quelque chose, n’hésitez pas à voter
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut Diagramme de classe -> Base de données
    Merci beaucoup ca m'a beaucoup aidé. et pour les cardinalités 0 a N et 1 a 1 aussi c'est la meme logique qu'il faut utiliser ?

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

    Poursuivons notre histoire de traduction du diagramme de classes en SQL.

    Pour les multiplicités 0..N, le film est le même que le précédent, à ceci près qu’une multiplicité 1..N impose la mise en oeuvre d’une contrainte SQL pour faire respecter la règle selon laquelle un service gère au moins une archive, contrainte absente dan le cas de la multiplicité 0..N.

    Vous avez aussi évoqué les multiplicités 1-1, alors allons-y...


    (3) Traduction d’une association de 1 à 1.

    Prenons le cas des agences qui ont un et un seul directeur, tandis qu’une personne ne peut diriger qu’une et une seule agence :


    Il y a manifestement une bijection entre les deux classes, mais ceci sera source de pièges avec SQL (présence d’un cycle). La symétrie parfaite dans le diagramme ci-dessous (automatiquement généré par PowerAMC) est flagrante : la clé primaire (<pk>) d’une table est forcément l’objet d’une contrainte référentielle — clé étrangère — (<fk>) pour l’autre, intégrité des données oblige. Mais selon le diagramme, il est seulement exigé que chaque valeur de l’attribut AgenceId de la table DIRECTEUR soit une valeur de l’attribut AgenceId de la table AGENCE, et que chaque valeur de l’attribut DirecteurId de la table AGENCE soit une valeur de l’attribut DirecteurId de la table DIRECTEUR :




    Mais, pour la table DIRECTEUR, on ne garantit en rien qu’une agence n’a qu’un directeur : en effet, on pourrait avoir la situation suivante où chaque directeur dirige une seule agence, mais où une agence pourrait avoir plusieurs directeurs :

    DIRECTEUR {DirecteurId    AgenceId    DirecteurNom}
               d1             a1          Fernand
               d2             a2          Paul
               d3             a1          Raoul
    
    Ainsi, l’agence a1 est dirigée à la fois par Fernand et Raoul...

    De même, pour la table AGENCE, on ne garantit pas qu’un directeur ne dirige qu’une agence :

    AGENCE {AgenceId    DirecteurId    AgenceNom}
            a1          d1             Yaoundé
            a2          d2             Lyon
            a3          d1             Rome
    
    Ainsi, le directeur d1 dirige à la fois les agences de Yaoundé et Rome...

    L’intégrité référentielle est respectée, mais pas les règles de gestion des données.

    Pour pallier les lacunes de l’AGL, on complète en faisant de {AgenceId} une clé alternative (<ak>) de DIRECTEUR et de {DirecteurId} une clé alternative de AGENCE :




    Dans ces conditions, l’agence a1 est dirigée soit par Fernand soit par Raoul, mais pas par les deux. De même, le directeur d1 dirige soit l’agence de Yaoundé soit celle de Rome, mais pas les deux.

    Et pourtant ! On voit dans le tableau ci-dessous que l’intégrité référentielle et les règles de gestion des données sont respectées au sein de chaque table, mais ces règles sont violées au niveau de la base de données : par exemple, selon la table DIRECTEUR, le directeur a1 ne dirige que l’agence d1, mais d’après la table AGENCE, ce directeur ne dirige que l’agence d2 !

    DIRECTEUR                              AGENCE
    +-------------+----------+             +----------+-------------+
    | DirecteurId | AgenceId |             | AgenceId | DirecteurId |
    |-------------+----------|             |----------+-------------|
    |          a1 |       d1 |             |       d1 |          a2 |
    |          a2 |       d2 |             |       d2 |          a1 |
    +-------------+----------+             +----------+-------------+ 
    
    Ce problème a évidemment une solution, mais à ce sujet je vous renvoie au billet que j’ai consacré au problème que posent les associations 1-1 (Merise : cardinalités 1,1 ---- 1,1 => intégrité référentielle = cautère sur jambe de bois).


    Prochain épisode : les associations M..N.
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    waooow !! merci. C'est meme maintenant que j'ai mieux assimilé la notion de contrainte sur les clé. j'suis aussi interessé par l'episode dont t'as parlé : M..N. et merci encore

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


    Suite du feuilleton. :


    (4) Traduction des associations N..M

    Selon votre diagramme de classes, un utilisateur a accès à au moins une archive, c’est d’accord, mais une archive n’est consultée que par un et un seul utilisateur, ce qui est pour le moins réducteur...

    Considérons l’association connectant ARCHIVE et UTILISATEUR, et donnons-lui un nom, par exemple CONSULTATION (je suppose qu’un utilisateur est là pour consulter, éplucher, plutôt que simplement admirer des archives...)

    Utilisons les règles suivantes :

    (RGa) Une archive peut être consultée par zéro à plusieurs utilisateurs (zéro, parce que certaines archives n’intéressent peut-être personne).

    (RGb) Un utilisateur a consulté au moins une archive.

    Evolution en conséquence du diagramme de classes :



    Au stade SQL, contrairement à ce qu’on a vu avec les multiplicités 1-1, on ne peut pas avoir la situation suivante :


    C'est-à-dire :

    SERVICE {idService    nomService}
             s1           facturation
             s2           abonnement
    
    ARCHIVE {idArchive    idService    nomArchive      id Utilisateur} 
             a1           s1           UML story       u1, u2, u3
             a2           s1           A ma santé      u2  
             a3           s2           Cours toujours  u2, u3
             a4           s1           La fin          u1, u3
    
    UTILISATEUR {idUtilisateur    nomUtilisateur    prenomUtilisateur    adresseUtilisateur    idArchive}
                 u1               Naudin            Fernand              Montauban             a1, a2, a3
                 u2               Volfoni           Raoul                Paris                 a2, a4  
                 u3               Volfoni           Paul                 Lille                 a21, a3  
    
    En effet, pour une ligne donnée de la table ARCHIVE, par définition, l’attribut idUtilisateur ne peut prendre qu’une valeur, et en aucun cas une liste quelconque de valeurs, du genre <u1, u2, u3> pour l’archive <a1> dans l’exemple. Ceci vaut bien sûr aussi pour l’attribut idArchive de la table UTILISATEUR. C’est par conformité à la logique du 1er ordre que cette contrainte est imposée.

    En conséquence, pour s’en sortir, la règle de passage du diagramme de classes au code SQL est la suivante : l’association CONSULTATION donne lieu à une table, on va dire associative, concentrant les liens entre les tables impliquées dans cette sombre histoire, c'est-à-dire ARCHIVE et UTILISATEUR :

    SERVICE {idService    nomService}
             s1           facturation
             s2           abonnement
    
    ARCHIVE {idArchive    idService    nomArchive} 
             a1           s1           UML story
             a2           s1           A ma santé
             a3           s2           Cours toujours
             a4           s1           La fin
    
    UTILISATEUR {idUtilisateur    nomUtilisateur    prenomUtilisateur    adresseUtilisateur}
                 u1               Naudin            Fernand              Montauban
                 u2               Volfoni           Raoul                Paris
                 u3               Volfoni           Paul                 Lille
    
    CONSULTATION {idArchive    idUtilisateur}
                  a1           u1
                  a1           u2
                  a1           u3
                  a2           u2
                  a3           u2
                  a3           u3
                  a4           u1
                  a4           u3
    
    Le diagramme logique dérivé du diagramme de classes doit être le suivant (et c’est bien celui que produit PowerAMC) :



    Code SQL :

     
    CREATE TABLE SERVICE 
    (
            idService            INT             NOT NULL
          , nomService           VARCHAR(48)     NOT NULL
        , CONSTRAINT SERVICE_PK PRIMARY KEY (idService)
    ) ;
    
    CREATE TABLE ARCHIVE 
    (
            idArchive            INT             NOT NULL
          , idService            INT             NOT NULL
          , nomArchive           VARCHAR(64)     NOT NULL
        , CONSTRAINT ARCHIVE_PK PRIMARY KEY (idArchive)
        , CONSTRAINT ARCHIVE_SERVICE_FK FOREIGN KEY (idService)
              REFERENCES SERVICE (idService)
    ) ;
    
    CREATE TABLE UTILISATEUR 
    (
            idUtilisateur        INT             NOT NULL
          , nomUtilisateur       VARCHAR(64)     NOT NULL
          , prenomUtilisateur    VARCHAR(32)     NOT NULL
          , adresseUtilisateur   VARCHAR(128)    NOT NULL
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (idUtilisateur)
    ) ;
    
    CREATE TABLE CONSULTATION 
    (
            idArchive            INT             NOT NULL
          , idUtilisateur        INT             NOT NULL
        , CONSTRAINT CONSULTATION_PK PRIMARY KEY (idArchive, idUtilisateur)
        , CONSTRAINT CONSULTATION_ARCHIVE_FK FOREIGN KEY (idArchive)
              REFERENCES ARCHIVE (idArchive)
        , CONSTRAINT CONSULTATION_UTILISATEUR_FK FOREIGN KEY (idUtilisateur)
              REFERENCES UTILISATEUR (idUtilisateur)
    ) ;
    
    Si pas de problème avec ça, la prochaine fois, si cela vous dit, on pourra passer aux classes-associations.
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    C'est vrai que j'suis un peu perdu sur la notion de clé alternative mais je vais essayer de fouiller encore plus mais en attendant on peut continuer sur ce que tu as evoqué. grand merci je debute le week-end avec un bon pied

  10. #10
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    (5) Traduction des classes-associations

    Supposons que l’on compte le nombre de fois où chaque utilisateur à consulté une archive. Par exemple Raoul a consulté 5 fois l’archive « La saga UML ». il faut pour cela mettre en oeuvre un attribut, nommons-le Comptage, et une classe-association ad-hoc l’hébergeant, nommons-la CONSULTATION :


    Ô magie, le code SQL produit est identique à celui qui a été produit la dernière fois, à ceci près que la table CONSULTATION a été enrichie de l’attribut Comptage (CONSULTER s’appelait CONSULTATION).

    CREATE TABLE SERVICE 
    (
            idService            INT             NOT NULL
          , nomService           VARCHAR(48)     NOT NULL
        , CONSTRAINT SERVICE_PK PRIMARY KEY (idService)
    ) ;
    
    CREATE TABLE ARCHIVE 
    (
            idArchive            INT             NOT NULL
          , idService            INT             NOT NULL
          , nomArchive           VARCHAR(64)     NOT NULL
        , CONSTRAINT ARCHIVE_PK PRIMARY KEY (idArchive)
        , CONSTRAINT ARCHIVE_SERVICE_FK FOREIGN KEY (idService)
              REFERENCES SERVICE (idService)
    ) ;
    
    CREATE TABLE UTILISATEUR 
    (
            idUtilisateur        INT             NOT NULL
          , nomUtilisateur       VARCHAR(64)     NOT NULL
          , prenomUtilisateur    VARCHAR(32)     NOT NULL
          , adresseUtilisateur   VARCHAR(128)    NOT NULL
          , NoBadgeUtilisateur   VARCHAR(12)     NOT NULL
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (idUtilisateur)
        , CONSTRAINT UTILISATEUR_AK UNIQUE (NoBadgeUtilisateur)
    ) ;
    
    CREATE TABLE CONSULTATION 
    (
            idArchive            INT             NOT NULL
          , idUtilisateur        INT             NOT NULL
          , Comptage             INT             NOT NULL
        , CONSTRAINT CONSULTATION_PK PRIMARY KEY (idArchive, idUtilisateur)
        , CONSTRAINT CONSULTATION_ARCHIVE_FK FOREIGN KEY (idArchive)
              REFERENCES ARCHIVE (idArchive)
        , CONSTRAINT CONSULTATION_UTILISATEUR_FK FOREIGN KEY (idUtilisateur)
              REFERENCES UTILISATEUR (idUtilisateur)
    ) ;
    

    Note concernant les clés alternatives

    Disons que les identifiants (donc les clés) sont de deux natures : naturels ou artificiels, tandis qu’ils ont tous pour objet de garantir l’unicité de l’information. Ainsi, j’ai ajouté un attribut NoBadgeUtilisateur pour la classe UTILISATEUR, mais comme deux utilisateurs ne peuvent pas avoir le même numéro de badge, l’attribut NoBadgeUtilisateur donne lieu à l’identifiant {NoBadgeUtilisateur}, donc à la clé alternative UTILISATEUR_AK pour la table UTILISATEUR (voir ci-dessus). L’attribut NoBadgeUtilisateur est naturel, il a une signification. L’identifiant et la clé qui en sont issus sont naturels. Par contre, les attributs idService, idArchive, idUtilisateur sont artificiels, n’ont aucune signification pour quiconque (et sont donc invariants), en fait ils devraient rester privés. Quoi qu’il en soit, une table ne devrait comporter qu’au moins et au plus une clé artificielle, désignée pour être clé primaire, ainsi que de 0 à N clés naturelles (de facto alternatives). Quelques exemples de clés naturelles : le numéro du badge d’un utilisateur, le numéro de sécurité sociale d’une personne, le matricule d’un employé, l’ISBN d’un ouvrage, le numéro de SIREN des entreprises françaises, le login d’un forumeur, etc.
    A noter encore qu’une clé artificielle peut être composite (plus d’un attribut), c’est le cas de la table CONSULTATION. Par contre, les clés naturelles n’ont guère de raison de l’être, elles sont singletons (un seul attribut) à moins que la modélisation soit défaillante.

    (6) Variation sur la traduction des classes-associations

    Supposons qu’au lieu de compter les consultations, on veuille savoir à quelles dates et pendant combien de temps un utilisateur a consulté telle archive. PowerAMC permet la modélisation suivante :


    L’attribut consultationId vient compléter la clé primaire, afin que l’on puisse distinguer chaque consultation d’une archive donnée par un utilisateur, ce que l’on avait pas besoin de faire dans l’exemple précédent. Le code SQL produit est identique au précédent, sauf bien sûr pour la table CONSULTATION :

    
    CREATE TABLE CONSULTATION 
    (
            idArchive                INT             NOT NULL
          , idUtilisateur            INT             NOT NULL
          , consultationId           INT             NOT NULL 
          , consultationDate         DATE            NOT NULL
          , consultattionHeureDebut  TIME            NOT NULL
          , consultattionHeureFin    TIME            NOT NULL
        , CONSTRAINT CONSULTATION_PK PRIMARY KEY (idArchive, idUtilisateur, consultationId)
         , CONSTRAINT CONSULTATION_ARCHIVE_FK FOREIGN KEY (idArchive)
              REFERENCES ARCHIVE (idArchive)
        , CONSTRAINT CONSULTATION_UTILISATEUR_FK FOREIGN KEY (idUtilisateur)
              REFERENCES UTILISATEUR (idUtilisateur)
    ) ;
    
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    Merci infiniment!!! je crois que je peux y arriver maintenant

  12. #12
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par Syntcpip Voir le message
    Merci infiniment!!! je crois que je peux y arriver maintenant
    En voilà une nouvelle qu’elle est bonne

    Vous pouvez compléter votre trousse à outils, selon les thèmes suivants, qui ont une influence sur le code SQL :

    — La composition (symbolisée par le losange noir porté par l’association Composant - Composite, à côté de la classe composite).

    — La variante de la classe-association COMPOSITION de suivi des dates de consultation (point 6 précédent), avec utilisation de la composition.

    — La spécialisation des classes (héritage).

    — Les associations ternaires.

    — Les actions de compensation en SQL (ressortissant au métabolisme des données).

    — L’auto-incrémentation des clés.

    Bref, c’est vous qui voyez...


    Quel est votre SGBD ?
    (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 à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    pour l'instant je connais MySQL

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

    Le script SQL que j'ai fourni fonctionne avec MySQL.

    Parmi les thèmes que j’ai proposés, y en a-t-il un que vous souhaiteriez aborder ?
    (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
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    Bonjour,
    les sujets qui m'interessent parmis ceux proposés sont pour l'instant
    • L'auto-incrementation des clés
    • La spécialisation des classes (héritage).
    • Les associations ternaires.

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

    Donc, allons-y pour l’auto-incrémentation.


    Auto-incrémentation

    Comme vous le savez, l’auto-incrémentation est un mécanisme que l’on sous-traite au SGBD, permettant de ne pas avoir à calculer nous-mêmes une valeur — dont nous nous contre-fichons — pour une colonne d’une table SQL, plus précisément d’une colonne entrant dans la composition de la clé primaire de la table.

    L’auto-incrémentation n’est pas décrite par la norme SQL, en conséquence de quoi chaque SGBD est libre (a) de la proposer, (b) sous la forme qui lui fait plaisir.

    Exemple, cas de la table SERVICE :

        MySQL
    
            idService            INT             NOT NULL    AUTO_INCREMENT 
    
        SQL SERVER
    
            idService            INT  IDENTITY   NOT NULL
    
        PostgreSQL 
    
            idService            SERIAL          NOT NULL    
    

    Le script cible (cf. post #10) devient donc le suivant :

    CREATE TABLE SERVICE 
    (
            idService            INT             NOT NULL    AUTO_INCREMENT 
          , nomService           VARCHAR(48)     NOT NULL
        , CONSTRAINT SERVICE_PK PRIMARY KEY (idService)
        , CONSTRAINT SERVICE_NOM_AK UNIQUE (nomService)
    ) ;
    
    CREATE TABLE ARCHIVE 
    (
            idArchive            INT             NOT NULL    AUTO_INCREMENT 
          , idService            INT             NOT NULL
          , nomArchive           VARCHAR(64)     NOT NULL
        , CONSTRAINT ARCHIVE_PK PRIMARY KEY (idArchive)
        , CONSTRAINT ARCHIVE_NOM_AK UNIQUE (nomArchive)
        , CONSTRAINT ARCHIVE_SERVICE_FK FOREIGN KEY (idService)
              REFERENCES SERVICE (idService)
    ) ;
    
    CREATE TABLE UTILISATEUR 
    (
            idUtilisateur        INT             NOT NULL    AUTO_INCREMENT 
          , nomUtilisateur       VARCHAR(64)     NOT NULL
          , prenomUtilisateur    VARCHAR(32)     NOT NULL
          , adresseUtilisateur   VARCHAR(128)    NOT NULL
          , NoBadgeUtilisateur   VARCHAR(12)     NOT NULL
        , CONSTRAINT UTILISATEUR_PK PRIMARY KEY (idUtilisateur)
        , CONSTRAINT UTILISATEUR_AK UNIQUE (NoBadgeUtilisateur)
    ) ;
    
    CREATE TABLE CONSULTATION 
    (
            idArchive                INT             NOT NULL
          , idUtilisateur            INT             NOT NULL
          , consultationId           INT             NOT NULL    AUTO_INCREMENT  
          , consultationDate         DATE            NOT NULL
          , consultattionHeureDebut  TIME            NOT NULL
          , consultattionHeureFin    TIME            NOT NULL
        , CONSTRAINT CONSULTATION_PK PRIMARY KEY (idArchive, idUtilisateur, consultationId)
        , CONSTRAINT CONSULTATION_ARCHIVE_FK FOREIGN KEY (idArchive)
              REFERENCES ARCHIVE (idArchive)
        , CONSTRAINT CONSULTATION_UTILISATEUR_FK FOREIGN KEY (idUtilisateur)
              REFERENCES UTILISATEUR (idUtilisateur)
    ) ;
    En ce qui concerne le diagramme de classes, il n’y a aucune raison pour que la notion d’auto-incrémentation au sens SQL soit proposée, puisqu’en fait elle se situe dans une « couche basse », c’est de la cuisine interne au SGBD.

    Dans le cas de la majorité des SGBD, pas de problème, ça fonctionne bien. Pour sa part, MySQL raisonne de façon totalement erronée : il part du principe que, puisqu’il y a incrémentation, alors la clé primaire ne doit comporter qu’une seule colonne. L’inférence est invalide, car fournir une valeur par incrémentation ou autre technique (par exemple hachage) est indépendant du rôle de la clé, qui, par définition, est d’être en dépendance fonctionnelle avec chaque colonne de la table ! Je rappelle qu’une clé primaire a tout intérêt à être composée de colonnes dont les valeurs n’ont aucune signification sémantique, ces colonnes doivent être purement artificielles, on pourrait dire inodores et sans saveur...

    En tout cas, à cause d’un raisonnement faux de la part du concepteur du SGBD, on doit modifier le code concernant la déclaration de la table CONSULTATION ; la clé primaire ci-dessus est reléguée au rang de clé alternative et {consultationId} devient illégitimement clé primaire :

    CREATE TABLE CONSULTATION 
    (
            idArchive                INT             NOT NULL
          , idUtilisateur            INT             NOT NULL
          , consultationId           INT             NOT NULL    AUTO_INCREMENT 
          , consultationDate         DATE            NOT NULL
          , consultationHeureDebut   TIME            NOT NULL
          , consultationHeureFin     TIME            NOT NULL
        , CONSTRAINT CONSULTATION_PK PRIMARY KEY (consultationId)
        , CONSTRAINT CONSULTATION_AK UNIQUE (idArchive, idUtilisateur, consultationId)
        , CONSTRAINT CONSULTATION_ARCHIVE_FK FOREIGN KEY (idArchive)
              REFERENCES ARCHIVE (idArchive)
        , CONSTRAINT CONSULTATION_UTILISATEUR_FK FOREIGN KEY (idUtilisateur)
              REFERENCES UTILISATEUR (idUtilisateur)
    ) ;
    
    Heureusement, il n’y a pas de bobo !

    Si vous utilisez PowerAMC, je rappelle la manip pour produire le code SQL de création des tables :

    Citation Envoyé par fsmrel Voir le message
    Vous commencez par générer un MPD (Modèle physique des données), en réalité un MLD (modèle logique des données) :

    Le diagramme de classes étant affiché, dans la barre de menus : OUTILS > Générer un modèle physique de données.

    Une fois ce MLD généré, dans la fenêtre correspondante : dans la barre de menus : SGBD > Générer la base de données.

    Au besoin, vous pouvez préciser votre SGBD : dans la barre de menus : SGBD > Editer le SGBD courant.
    D’une manière générale, indépendamment du SGBD, au stade MLD l’auto-incrémentation est prévue, il suffit de cocher la case Identity pour la colonne faisant l’objet de la clé primaire de la table. Par exemple, dans le cas de la table SERVICE :



    Dans le cas de MySQL, pour éviter de toucher au MLD, et ne le faire que dans le code SQL, demander une vérification du MLD (Outils > Vérifier le modèle, ou touche de fonction F4) et décocher la case « Clé à incrémentation automatique :



    Ceci fait, vous pourrez générer le script SQL, et apporter la modification concernant la clé primaire de la table CONSULTATION.

    Bonus : un petit jeu de test


    INSERT INTO SERVICE (nomService) VALUES ('Service Un') ;
    INSERT INTO SERVICE (nomService) VALUES ('Service Deux') ;
    INSERT INTO SERVICE (nomService) VALUES ('Service Trois') ;
    
    SELECT * FROM SERVICE ;
    
    INSERT INTO ARCHIVE (idService, nomArchive) 
        SELECT idService , 'Archive Un' FROM SERVICE WHERE nomService = 'Service Trois' ;
    
    INSERT INTO ARCHIVE (idService, nomArchive) 
        SELECT idService , 'Archive Deux' FROM SERVICE WHERE nomService = 'Service Trois' ;
    
    INSERT INTO ARCHIVE (idService, nomArchive) 
        SELECT idService , 'Archive Trois' FROM SERVICE WHERE nomService = 'Service Un' ;
    
    SELECT * FROM ARCHIVE ;
    
    INSERT INTO UTILISATEUR (nomUtilisateur, prenomUtilisateur, adresseUtilisateur, NoBadgeUtilisateur) VALUES ('Volfoni', 'Raoul', 'La péniche', 'Y0007') ;
    INSERT INTO UTILISATEUR (nomUtilisateur, prenomUtilisateur, adresseUtilisateur, NoBadgeUtilisateur) VALUES ('Volfoni', 'Paul', 'La péniche', 'X0123') ;
    INSERT INTO UTILISATEUR (nomUtilisateur, prenomUtilisateur, adresseUtilisateur, NoBadgeUtilisateur) VALUES ('Naudin', 'Fernand', 'Montauban', 'X0004') ;
    
    SELECT * FROM UTILISATEUR ;
    
    INSERT INTO CONSULTATION (idArchive, idUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin) 
        SELECT idArchive, (SELECT idUtilisateur FROM UTILISATEUR WHERE NoBadgeUtilisateur = 'X0004'), '2018-08-01', '09:00:00', '16:30:00' FROM ARCHIVE WHERE nomArchive = 'Archive Deux' ;
    
    INSERT INTO CONSULTATION (idArchive, idUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin) 
        SELECT idArchive, (SELECT idUtilisateur FROM UTILISATEUR WHERE NoBadgeUtilisateur = 'X0004'), '2018-08-02', '14:00:00', '18:00:00' FROM ARCHIVE WHERE nomArchive = 'Archive Deux' ;
    
    INSERT INTO CONSULTATION (idArchive, idUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin) 
        SELECT idArchive, (SELECT idUtilisateur FROM UTILISATEUR WHERE NoBadgeUtilisateur = 'Y0007'), '2018-08-05', '13:00:00', '14:00:00' FROM ARCHIVE WHERE nomArchive = 'Archive Deux' ;
    
    INSERT INTO CONSULTATION (idArchive, idUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin) 
        SELECT idArchive, (SELECT idUtilisateur FROM UTILISATEUR WHERE NoBadgeUtilisateur = 'X0123'), '2018-08-02', '12:00:00', '19:00:00' FROM ARCHIVE WHERE nomArchive = 'Archive Trois' ;
    
    SELECT * FROM CONSULTATION ;
    
    CREATE VIEW CONSULTATION_V01 (nomService, nomArchive, NoBadgeUtilisateur, nomUtilisateur, prenomUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin)
    AS SELECT nomService, nomArchive, NoBadgeUtilisateur, nomUtilisateur, prenomUtilisateur, consultationDate, consultationHeureDebut, consultationHeureFin 
       FROM   CONSULTATION AS x JOIN UTILISATEUR AS y ON x.idUtilisateur = y.idUtilisateur
                                JOIN ARCHIVE AS z ON x.idArchive = z.idArchive
                                JOIN SERVICE AS t ON z.idService = t.idService 
    ;
    
    SELECT * FROM CONSULTATION_V01 ;
    

    A suivre...
    (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. #17
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2014
    Messages : 15
    Points : 19
    Points
    19
    Par défaut
    merci pour les explications et j'attends avec impatience la suite mais avant j'ai une question sur les clés à valeur auto-increment sur MySQL : Y'a t-il une propabilité d'avoir une meme clé sur deux enregistrements differents si les bien evidemment les deux sont executés au "meme moment" ?

  18. #18
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Citation Envoyé par Syntcpip Voir le message
    j'ai une question sur les clés à valeur auto-increment sur MySQL : Y'a t-il une probabilité d'avoir une même clé sur deux enregistrements différents si les bien évidemment les deux sont exécutés au "même moment" ?
    Il y a bientôt 10 ans, j’avais évoqué la concurrence des accès (verrouillage) dans le cas général (post #22 de la discussion, forum Schéma).

    Je ne suis pas spécialiste de MySQL, mais je suppose que ses parents ont suivi scrupuleusement les recommandations d’usage (vieilles de 40 ans et éprouvées) concernant les propriétés ACID (atomicity, correctness, isolation, durability), donc avec un mécanisme de verrouillage imposant la sérialisation des opérations (c'est-à-dire garantissant une incrémentation correcte) et interdisant la mise à jour non contrôlée des tables en simultané. Autrement dit, à condition d’utiliser le moteur InnoDB (plutôt que le moteur MyISAM qui, je crois, est laxiste quant à l'« acidité », donc dangereux), les doublons de clés ne devraient pas exister (qu’on utilise l’auto-incrémentation ou une autre technique). Posez tout de même la question dans le forum MySQL, où les spécialistes de ce SGBD pourront vous donner leur avis.
    (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. #19
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Syntcpip,


    Regardons du côté de la spécialisation (l’« héritage »).

    Partons du diagramme suivant, représentant (partiellement) les personnes auxquelles s’intéresse la société Dubicobit, à savoir ses clients et fournisseurs (les tiers) ainsi que ses collaborateurs (diagramme à rapprocher de son jumeau) :



    On observe que de la classe PERSONNE sont issues deux classes spécialisées, à savoir COLLABORATEUR (les collaborateurs de Dubicobit) et TIERS (clients et fournisseurs), chacune avec ses attributs qui n’ont pas de sens pour l’autre. Que serait en effet un NIR (numéro de sécurité sociale) pour un tiers (c'est-à-dire une entreprise) ? Que serait pour un collaborateur un numéro Siret (code des établissements des entreprises en France) ? Les attributs qui sont pertinents à la fois pour les tiers et les collaborateurs sont regroupés dans la classe PERSONNE (cas en l’occurrence des attributs PersonneCode et AdresseCourriel), de même que sont affectés à cette classe les liens avec certaines autres classes (cas en l’occurrence du lien avec la classe ADRESSE).

    A son tour, la classe COLLABORATEUR se spécialise en EMPLOYE et DIRECTEUR.

    Pour sa part la classe ADRESSE est associée à la classe PERSONNE par une relation de composition : ADRESSE représente une propriété multivaluée de PERSONNE, qu’on a externalisée pour éviter de tomber dans les problèmes de manipulation inhérents à la logique du 2e ordre (pas de panique, ça n’est pas un gros mot, ne vous attardez pas à moins de plonger dans les articles de E.F. Codd, Derivability, Redundancy and Consistency of Relations Stored in Large Data Banks] et A Relational Model of Data for Large Shared Data Banks).

    Le code SQL correspondant est présent ci-dessous. Quelques remarques à son sujet :

    Auto-incrémentation : ça fonctionne comme dans mon précédent message, en notant que pour la table ADRESSE, comme dans le cas de la table CONSULTATION, étant donné que MySQL confond guitare et naviguer : parce que la colonne AdresseId est auto-incrémentée, cette andouille exige que le singleton {AdresseId} soit illégitimement clé primaire, au détriment de la paire {PersonneId, AdresseId} ravalée au rang de clé alternative. Je rappelle que ce n’est pas parce que les valeurs prises par la colonne AdresseId sont auto-incrémentées (c’est de la cuisine sous le capot) qu’il faille pour autant lui donner un sens sémantique.

    Attributs naturels et artificiels : ServiceId, PersonneId, AdresseId, sont les seuls attributs artificiels, donc non visibles par l’utilisateur qui ne connaît que les attributs naturels, c'est-à-dire tous les autres.

    Clés alternatives : outre la paire {PersonneId, AdresseId} réduite au rang de clé alternative, parce qu’elles sont issues d’attributs naturels, les autres clés alternatives permettent à l’utilisateur d’accéder à l’information : {ServiceCode}, {PersonneCode}, {AdresseCourriel}, {NoSiret}, {Matricule}, {NIR} : voyez par exemple le codage des INSERT.

    Actions de compensation : il s’agit ici du métabolisme des données. Par exemple, quelles sont les conséquences d’une tentative de suppression d’un service qui emploie des collaborateurs ? Un stimulus est transmis aux collaborateurs (table COLLABORATEUR) et il est évident que cette tentative doit être rejetée par ces personnes qui ne veulent pas être indirectement supprimées à leur tour. Par contre, quelles sont les conséquences d’une tentative de suppression directe d’une personne ? Supposons qu’il s’agisse de Raoul. Ça n’est pas parce qu’il est collaborateur et même directeur qu’il existe un obstacle à sa disparition et à celle de ses adresses. Techniquement on précise la chose au SGBD à l’aide de la clause « ON DELETE CASCADE » dans la déclaration des clés étrangères : ADRESSE_PERSONNE_FK, TIERS_PERSONNE_FK, COLLABORATEUR_PERSONNE_FK, DIRECTEUR_COLLABORATEUR_FK, EMPLOYE_COLLABORATEUR_FK. En tentant la suppression de Raoul dans la table PERSONNE, un stimulus part vers ses adresses, ainsi que vers Raoul en tant que collaborateur et par effet en cascade vers Raoul en tant que directeur. Comme rien ne s’y oppose (tout au long il n’y a que des « ON DELETE CASCADE »), alors Raoul disparaîtra dans toutes les tables où il est présent. Vous ferez le test ! En l’absence de cette action de compensation « ON DELETE CASCADE », il faudrait commencer par supprimer Raoul au niveau le plus bas (feuille), à savoir dans la table DIRECTEUR, puis au niveau noeud intermédiaire (COLLABORATEUR), et enfin au niveau racine (PERSONNE) sans oublier d’avoir aussi supprimé ses adresses.


    Code SQL de création des tables

    CREATE TABLE SERVICE
    (
            ServiceId            INT           NOT NULL    AUTO_INCREMENT 
          , ServiceCode          VARCHAR(8)    NOT NULL
         , ServiceLibelle        VARCHAR(32)   NOT NULL
        , CONSTRAINT SERVICE_PK PRIMARY KEY (ServiceId)
        , CONSTRAINT SERVICE_CODE_AK UNIQUE (ServiceCode)    
    );
    
    CREATE TABLE PERSONNE
    (
            PersonneId           INT           NOT NULL    AUTO_INCREMENT
          , PersonneCode         CHAR(8)       NOT NULL
          , AdresseCourriel      VARCHAR(64)   NOT NULL
        , CONSTRAINT PERSONNE_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT PERSONNE_CODE_AK UNIQUE (PersonneCode)
        , CONSTRAINT PERSONNE_COURRIEL_AK UNIQUE (AdresseCourriel)
    );
    
    CREATE TABLE ADRESSE
    (
            PersonneId           INT           NOT NULL
          , AdresseId            INT           NOT NULL    AUTO_INCREMENT
          , AdresseLigne2        VARCHAR(64)   NOT NULL
          , AdresseLigne3        VARCHAR(64)   NOT NULL DEFAULT ''
          , AdresseLigne4        VARCHAR(64)   NOT NULL DEFAULT ''
          , AdresseCodePostal    VARCHAR(6)    NOT NULL
        , CONSTRAINT ADRESSE_PRETENDUE_PK PRIMARY KEY (AdresseId)
        , CONSTRAINT ADRESSE_LEGITIME_PK UNIQUE (PersonneId, AdresseId)
        , CONSTRAINT ADRESSE_PERSONNE_FK FOREIGN KEY (PersonneId)
              REFERENCES PERSONNE (PersonneId) ON DELETE CASCADE
    );
    
    CREATE TABLE TIERS
    (
            PersonneId           INT           NOT NULL
          , NoSiret              CHAR(14)      NOT NULL
          , RaisonSociale        VARCHAR(64)   NOT NULL
        , CONSTRAINT TIERS_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT TIERS_SIRET_AK UNIQUE (NoSiret)
        , CONSTRAINT TIERS_PERSONNE_FK FOREIGN KEY (PersonneId)
              REFERENCES PERSONNE (PersonneId) ON DELETE CASCADE
    );
    
    CREATE TABLE COLLABORATEUR
    (
            PersonneId           INT           NOT NULL
          , ServiceId            INT           NOT NULL
          , Matricule            CHAR(8)       NOT NULL
          , NIR                  CHAR(13)      NOT NULL
          , Nom                  VARCHAR(32)   NOT NULL
          , Prenom               VARCHAR(32)   NOT NULL
          , DateEmbauche         DATE          NOT NULL
          , Salaire              INT           NOT NULL
        , CONSTRAINT COLLABORATEUR_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT COLLABORATEUR_MATRICULE_AK UNIQUE (Matricule)
        , CONSTRAINT COLLABORATEUR_NIR_AK UNIQUE (NIR)
        , CONSTRAINT COLLABORATEUR_PERSONNE_FK FOREIGN KEY (PersonneId)
              REFERENCES PERSONNE (PersonneId) ON DELETE CASCADE
        , CONSTRAINT COLLABORATEUR_SERVICE_FK FOREIGN KEY (ServiceId)
              REFERENCES SERVICE (ServiceId) ON DELETE NO ACTION
    );
    
    CREATE TABLE DIRECTEUR
    (
            PersonneId           INT           NOT NULL
          , PrimeBilan           INT           NOT NULL
        , CONSTRAINT DIRECTEUR_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT DIRECTEUR_COLLABORATEUR_FK FOREIGN KEY (PersonneId)
              REFERENCES COLLABORATEUR (PersonneId) ON DELETE CASCADE
    );
    
    CREATE TABLE EMPLOYE
    (
            PersonneId           INT           NOT NULL
          , Profil               VARCHAR(128)  NOT NULL
        , CONSTRAINT EMPLOYE_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT EMPLOYE_COLLABORATEUR_FK FOREIGN KEY (PersonneId)
          REFERENCES COLLABORATEUR (PersonneId) ON DELETE CASCADE
    );
    
    (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
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Pour aider aux tests :

    INSERT INTO SERVICE (ServiceCode, ServiceLibelle) VALUES ('DSI', 'Informatique') ;
    INSERT INTO SERVICE (ServiceCode, ServiceLibelle) VALUES ('DRH', 'Personnel') ;
    INSERT INTO SERVICE (ServiceCode, ServiceLibelle) VALUES ('COMPTA', 'Comptabilité') ;
    
    SELECT * FROM SERVICE ;
    
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('T0000001', 'dépannage.naudin@abc.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('T0000002', 'volfoni-freres@xyzt.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('N0000001', 'f.naudin@abc.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('V0000001', 'r.volfoni@xyzt.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('V0000002', 'p.volfoni@xyzt.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('P0000001', 'pascal@citron.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('P0000002', 'bastien@citron.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('N0000002', 'me.folace@machin.fr') ;
    INSERT INTO PERSONNE (PersonneCode, AdresseCourriel) VALUES ('N0000003', 'jean@machin.fr') ;
    
    SELECT * FROM PERSONNE ;
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Montauban', '82000' FROM PERSONNE WHERE PersonneCode = 'N0000001' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Montauban', '82000' FROM PERSONNE WHERE PersonneCode = 'T0000001' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Paris', '75015' FROM PERSONNE WHERE PersonneCode = 'T0000002' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Paris', '75015' FROM PERSONNE WHERE PersonneCode = 'V0000001' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Paris', '75015' FROM PERSONNE WHERE PersonneCode = 'V0000002' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Paris', '75015' FROM PERSONNE WHERE PersonneCode = 'P0000001' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Paris', '75015' FROM PERSONNE WHERE PersonneCode = 'P0000002' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Rueil', '92063' FROM PERSONNE WHERE PersonneCode = 'N0000002' ; 
    
    INSERT INTO ADRESSE (PersonneId, AdresseLigne2, AdresseCodePostal) 
        SELECT PersonneId, 'Rueil', '92063' FROM PERSONNE WHERE PersonneCode = 'N0000003' ; 
    
    SELECT * FROM ADRESSE ;
    
    INSERT INTO TIERS (PersonneId, NoSiret, RaisonSociale) 
        SELECT PersonneId, '12345678901234', 'Naudin dépannage' FROM PERSONNE WHERE PersonneCode = 'T0000001' ; 
    
    INSERT INTO TIERS (PersonneId, NoSiret, RaisonSociale) 
        SELECT PersonneId, '23456789012345', 'Volfoni associés' FROM PERSONNE WHERE PersonneCode = 'T0000002' ; 
    
    SELECT * FROM TIERS ;
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DRH'), 'MAT00078', '1190792124007', 'Naudin', 'Fernand', '1963-04-01', 10000 FROM PERSONNE WHERE PersonneCode = 'N0000001' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DSI'), 'MAT00013', '1160192124014', 'Volfoni', 'Raoul', '1961-11-03', 15000 FROM PERSONNE WHERE PersonneCode = 'V0000001' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DSI'), 'MAT00014', '1191059004009', 'Volfoni', 'Paul', '1961-11-03', 15000 FROM PERSONNE WHERE PersonneCode = 'V0000002' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DSI'), 'MAT00056', '1300450012003', '', 'Pascal', '1963-12-05', 6000 FROM PERSONNE WHERE PersonneCode = 'P0000001' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DSI'), 'MAT00057', '1130640012028', '', 'Bastien', '1963-12-05', 6000 FROM PERSONNE WHERE PersonneCode = 'P0000002' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'DRH'), 'MAT00002', '1030779370005', '', 'Jean', '1961-01-25', 3000 FROM PERSONNE WHERE PersonneCode = 'N0000002' ; 
    
    INSERT INTO COLLABORATEUR (PersonneId, ServiceId, Matricule, NIR, Nom, Prenom, DateEmbauche, Salaire) 
        SELECT PersonneId, (SELECT ServiceId FROM SERVICE WHERE ServiceCode = 'COMPTA'), 'MAT00003', '1210775007098', 'Folace', '', '1961-01-26', 5000 FROM PERSONNE WHERE PersonneCode = 'N0000003' ; 
    
    SELECT * FROM COLLABORATEUR ;
    
    INSERT INTO DIRECTEUR (PersonneId, PrimeBilan)
        SELECT PersonneId, 15000 FROM PERSONNE WHERE PersonneCode = 'N0000001' ; 
    
    INSERT INTO DIRECTEUR (PersonneId, PrimeBilan)
        SELECT PersonneId, 17000 FROM PERSONNE WHERE PersonneCode = 'V0000001' ; 
    
    INSERT INTO DIRECTEUR (PersonneId, PrimeBilan)
        SELECT PersonneId, 17000 FROM PERSONNE WHERE PersonneCode = 'V0000002' ; 
    
    SELECT * FROM DIRECTEUR ;
    
    INSERT INTO EMPLOYE (PersonneId, Profil)
        SELECT PersonneId, 'Première gâchette' FROM PERSONNE WHERE PersonneCode = 'P0000001' ; 
    
    INSERT INTO EMPLOYE (PersonneId, Profil)
        SELECT PersonneId, 'Première gâchette' FROM PERSONNE WHERE PersonneCode = 'P0000002' ; 
    
    INSERT INTO EMPLOYE (PersonneId, Profil)
        SELECT PersonneId,  'majordome' FROM PERSONNE WHERE PersonneCode = 'N0000002' ; 
    
    INSERT INTO EMPLOYE (PersonneId, Profil)
        SELECT PersonneId,  'notaire' FROM PERSONNE WHERE PersonneCode = 'N0000003' ; 
    
    SELECT * FROM EMPLOYE ;
    
    (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.

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

Discussions similaires

  1. passage de diagramme de classe vers base de donnée access
    Par abboudi dans le forum Modélisation
    Réponses: 5
    Dernier message: 28/02/2016, 22h53
  2. Réponses: 0
    Dernier message: 25/07/2011, 17h49
  3. [WD16] Classe et base de données
    Par Pascal26120 dans le forum WinDev
    Réponses: 6
    Dernier message: 18/03/2011, 08h32
  4. classes JPA ==> Base de données
    Par goldenman84 dans le forum Spring Web
    Réponses: 0
    Dernier message: 24/06/2010, 01h22
  5. Diagramme réseau avec source base de données
    Par anthony_rexis dans le forum Windows Forms
    Réponses: 1
    Dernier message: 29/10/2008, 14h52

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