Bonsoir Redreams,
Envoyé par
Redreams
pour l'histoire des catégorie j'ai donc rattaché SOUS_CATEGORIE uniquement à CATEGORIE et ainsi déplacer la relation AVOIR (qui allait de PHOTO à SOUS CATEGORIE) directement sur CATEGORIE. Enfin je crois que c'était cela qu'il fallait faire !?
Comme je l’ai évoqué dans me message #8 à propos de l’entité-type DETAIL_SELECTION_PHOTO, il est des entités-types qui sont faibles par rapport à d’autres : il in est ainsi de SOUS_CATEGORIE_PHOTO par rapport à CATEGORIE_PHOTO. Mais ça n’est pas pour autant qu’il faille changer les règles de gestion des données : les règles R3 et R4 présentes dans le message #7 restent d’actualité, l’entité-type PHOTO reste associée à l’entité-type (faible) SOUS_CATEGORIE_PHOTO :
Envoyé par
Redreams
c'est l'administrateur qui gère à la fois les séances, et les catégories
La réponse est ambiguë. Je repose ma question différemment :
Une séance est du ressort d’un administrateur (règles R14, R15). Si l’administrateur Albert gère ses catégories, l’administrateur Bernard peut-il gérer les séances des photos correspondantes à la place d’Albert ?
Mais si vous êtes pressé par le temps, on laisse le MCD en l’état, il n’y a pas péril en la demeure.
Dans les diagrammes précédents, une photo était attachée à au moins et au plus une séance, mais dans votre dernier MCD, « au moins » a été remplacé par « 0 » : ce changement est important. Que s’est-il passé ? Il y a des photos hors séance ? donc ne correspondant à aucun client ?
A propos des contraintes de chemin :
Au vu du diagramme ci-dessous, le client Raoul peut demander une séance de photos Sn1, laquelle pourra regrouper les sélections Sel1, Sel2, etc. Cela dit, rien n’interdit du point de vu du MCD de brancher le client Fernand sur une ou plusieurs de ces sélections :
Ainsi, on pourrait parfaitement avoir la situation suivante au stade SQL, sans que le SGBD et les contraintes référentielles n’y voient d’inconvénient :
CLIENT
id_utilisateur ...
1 ...
2 ...
SEANCE_PHOTO
id_seance id_utilisateur ...
1 1
SELECTION_PHOTO
id_selection_photo id_seance id_utilisateur
1 1 2
Conclusion : l’utilisateur 2 a accès aux photos de l’utilisateur 1...
Pour éviter cette situation fâcheuse, on considère SEANCE_PHOTO comme une entité-type faible (donc non autonome) relativement à l’entité-type CLIENT (ce qui est sémantiquement parfaitement légitime, puisqu’une séance est viscéralement attachée à un client). On matérialise la chose en identifiant SEANCE_PHOTO relativement à CLIENT. Pour les mêmes raisons, on pourrait identifier SELECTION_PHOTO relativement à SEANCE_PHOTO, et on pourrait aussi identifier SELECTION_PHOTO relativement à CLIENT, mais on peut éventuellement s’en dispenser :
Conséquence : au stade SQL, l’attribut id_utilisateur est intégré à la clé primaire de la table SEANCE_PHOTO, clé qui n’est plus le singleton {id_seance}, mais la paire {id_utilisateur, id_seance}.
La situation devient la suivante :
id_utilisateur ...
1 ...
2 ...
SEANCE_PHOTO
id_utilisateur id_seance ...
1 1 ...
SELECTION_PHOTO
id_selection_photo id_utilisateur_A id_seance id_utilisateur_B
1 1 1 2
Où {id_selection_photo, id_utilisateur_A} est une clé étrangère héritée de SEANCE_PHOTO (conséquence de l’association Regrouper_selection), et {id_utilisateur_B} est une clé étrangère héritée de CLIENT (conséquence de l’association Creer_selection).
Comme on ne veut pas mélanger les photos des uns et des autres, on supprime l’attribut id_utilisateur_B et l’on rend à sa place {id_utilisateur_A} clé étrangère relativement à CLIENT. Maintenant, conséquence de l’identification relative, on a deux chemins redondants pour accéder à une sélection :
CLIENT > Demander_seance > SEANCE_PHOTO > Regrouper_selection > SELECTION_PHOTO ;
CLIENT > Creer_selection > SELECTION_PHOTO.
Il y a redondance, on supprime donc un chemin. Le 1er est évidemment à conserver, alors que le 2e est manifestement inutile, on le supprime, et le MCD devient :
Je vous vois tousser, mais il n’empêche qu’avec cette représentation non redondante, on n’en est pas moins capable de créer et consulter des sélections, tout en empêchant les mélanges entre clients...
Pour rester dans la logique des entités-types faibles, on peut très bien identifier SELECTION_PHOTO relativement à SEANCE_PHOTO (ainsi, l’attribut id_utilisateur sera propagé jusqu’à DETAIL_SELECTION_PHOTO, ce qui peut simplifier les requêtes et la vie de l’optimiseur du SGBD, c'est-à-dire booster les performances) :
A y regarder de près, on pourrait aussi mélanger les commandes d’un client A avec celles d’un client B, il y a en effet deux chemins pour aller de CLIENT à COMMANDE :
CLIENT > COMMANDE ;
CLIENT > Demander_seance > SEANCE_PHOTO > Regrouper_selection > SELECTION_PHOTO > déclencher > COMMANDE.
Pour empêcher les mélanges, on agit cette fois-ci au niveau MLD/MPD, car tous les liens sont ici essentiels, on ne peut en supprimer aucun. Même pas grave, on agit au niveau MPD (voir plus loin).
Envoyé par
Redreams
Je me rend compte que beaucoup d'attributs apparaissent à des endroits et je ne comprends pas pourquoi ils apparaissent dans certaines tables !
Par exemple dans si on prend la table CATEGORIE_PHOTO dans le MPD on voit " id_utilisateur " mais pourquoi il se pointe la lui ! Ou alors " Admin_id_utilisateur " dans commande ! J'ai l'impréssion que dès que je me débloque quelques part il y a un nouveau soucis qui apparait ! C'est comme faire du pédalo sans être sur de l'eau ! Je pédale, je pédale mais j'avance pas !
Prenons le cas de l’attribut id_utilisateur. Au niveau MCD, il n’apparaît qu’une fois, à savoir dans le surtype UTILISATEUR. Au niveau MLD/MPD, il doit être répliqué dans les tables CLIENT et ADMINISTRATEUR, car il sert pour les jointures entre tables UTILISATEUR et CLIENT d’une part, et les jointures entre les tables UTILISATEUR et ADMINISTRATEUR d’autre part. C’est comme cela que Ted Codd a vu les choses en 1969 en créant le modèle relationnel de données (voyez son article fondateur de 1970, A Relational Model of Data for Large Shared Data Banks) : pas de pointeurs pour accéder à l’information, mais comparaison entre les valeurs des attributs. En outre, cette réplication sert pour l’intégrité référentielle : si l’attribut id_utilisateur prend la valeur 12345 dans la table CLIENT, cette valeur doit exister pour l’attribut id_utilisateur de la table UTILISATEUR, sinon : bug ! par exemple, si 12345 est absent de la table UTILISATEUR, comment se nommerait cet utilisateur 12345 ? Allez savoir... Dans une société de crédit automobile, il y a une trentaine d’années de cela, j’avais constaté l’existence de tonnes de contrats faisant référence à des clients inconnus ou bataillon, évaporés ! (tant pis pour la société en question, mais grâce aux sauvegardes, on a pu récupérer les associations manquantes, ouf !)
Maintenant, il est bien dit qu’une catégorie de photos est gérée par un administrateur : pour effectuer la jointure entre les tables ADMINISTRATEUR et CATEGORIE_PHOTO, c’est encore l’attribut id_utilisateur qui va servir.
L’attribut Admin_id_utilisateur vous interpelle : c’est lui va servir pour effectuer la jointure entre les tables ADMINISTRATEUR et COMMANDE, pour savoir quel administrateur valide quelle commande. En l’occurrence, dans COMMANDE, PowerAMC a nommé ainsi l’attribut parce que id_utilisateur est déjà utilisé pour le lien avec CLIENT.
Le MPD
A ce niveau, Il y a une fenêtre à connaître, qui permet de savoir quelles colonnes de quelles tables servent pour les associations entre celles-ci, c’est la fenêtre « Propriétés de la référence ». Par exemple, pour repérer les colonnes joignant les tables ADMINISTRATEUR et SEANCE_PHOTO on fait un clic droit sur le lien (R7 ou R8 chez vous je pense), d’où ouverture de la fenêtre qui va bien, et dans laquelle on voit dans l’exemple ci-dessous que c’est la colonne id_utilisateur de la table parente ADMINISTRATEUR qui est à joindre avec la colonne id_utilisateur_admin de la table SEANCE_PHOTO :
Examinons maintenant le MPD que m’a généré l’AGL (je n’ai pas tout mis, par exemple les commentaires sont absents) :
Table UTILISATEUR : rien à signaler.
Table ADMINISTRATEUR : rien à signaler. A noter que l’attribut id_utilisateur est à la fois clé primaire et clé étrangère (celle-ci permet de faire référence à la clé primaire {id_utilisateur} de la table UTILISATEUR.
Table CATEGORIE_PHOTO : rien à signaler. La colonne id_utilisateur permet de savoir quel administrateur gère quelle catégorie.
Table SOUS_CATEGORIE_PHOTO : comme l’entité-type SOUS_CATEGORIE_PHOTO a été identifiée relativement à l’entité-type CATEGORIE_PHOTO, la clé primaire est la paire {id_categorie_photo, id_sous_categorie_photo}.
Table PHOTO : comme dans d’autres tables, on a un attribut CLI_id_utilisateur, qui sert manifestement à la jointure des tables SEANCE_PHOTO et PHOTO (on s’en assure en ouvrant la fenêtre « Propriétés de la référence »). L’attribut id_seance binôme avec CLI_id_utilisateur, car la paire {CLI_id_utilisateur, id_seance} est clé étrangère, elle référence la clé primaire {CLI_id_utilisateur, id_seance} de la table SEANCE_PHOTO. On retrouve la paire {id_categorie_photo, id_sous_categorie_photo}, en qualité de clé étrangère, elle référence la clé primaire {id_categorie_photo, id_sous_categorie_photo} de la table SOUS_CATEGORIE_PHOTO. Incidemment, grâce à la présence de l’attribut id_categorie_photo, on sait tout de suite quelle est la catégorie de la photo.
Table CLIENT : rien à signaler. Plus tard, pour des raisons évidentes de convivialité et d’homogénéité avec autres attributs de la table, je renommerai l’attribut id_utilisateur en id_client.
Table SEANCE_PHOTO : comme « CLI_id_utilisateur » ça n’est pas très beau comme nom, je le remplacerai par « id_client », en m’étant d’abord assuré, grâce à la fenêtre « Propriétés de la référence » que je ne suis pas à côté de la plaque, et j’en ferai autant au fur et mesure pour les autres tables. Pour sa part, l’attribut id_utilisateur_admin permet de faire la jointure avec la table ADMINISTRATEUR.
Table SELECTION_PHOTO : du fait de l’identification relative à SEANCE_PHOTO, cette table a pour clé primaire le triplet {CLI_id_utilisateur, id_seance, id_selection} où id_selection sert à dédoublonner les paires {CLI_id_utilisateur, id_seance}.
Table DETAIL_SELECTION_PHOTO : même principe.
Table COMMANDE : y a du monde en ce qui concerne les clés étrangères ! Le singleton {id_utilisateur_admin} est clé étrangère par rapport à la clé primaire {id_utilisateur_admin} de la table ADMINISTRATEUR, ce qui permet de savoir quel administrateur gère et valide quelle commande.
Pour savoir quelles colonnes de la table COMMANDE sont en relation avec quelles colonnes de la table SELECTION_PHOTO :
Pour savoir quelles colonnes de la table COMMANDE sont en relation avec quelles colonnes de la table CLIENT :
On constate à cette occasion qu’on deux fois affaire au client : une 1re fois avec l’attribut SEL_CLI_id_utilisateur et une 2e fois avec l’attribut id_utilisateur : on retrouve le problème de la contrainte de chemin laissé en suspens plus haut :
CLIENT > COMMANDE ;
CLIENT > Demander_seance > SEANCE_PHOTO > Regrouper_selection > SELECTION_PHOTO > déclencher > COMMANDE.
La solution consiste à ne conserver qu’un des deux attributs, par exemple id_utilisateur. Mais on demande d’abord à l’AGL de joindre COMMANDE et SELECTION_PHOTO non plus sur SEL_CLI_id_utilisateur, mais sur id_utilisateur.
Dans un 1er temps, on attaque la liste déroulante qui va bien :
Dans un 2e temps, on clique sur id_utilisateur : c’est bien désormais la colonne id_utilisateur qui sert pour la jointure avec la table SELECTION_PHOTO :
Et au niveau du diagramme, c’est net, on voit que l’attribut id_utilisateur participe aux deux clés étrangères (symbolisées par le mickey <fk1,fk3>). On constate aussi que l’AGL a supprimé l’attribut SEL_CLI_id_utilisateur devenu inutile (il ne l’aurait pas fait que je m’en serais chargé) :
Il ne doit pas manquer grand-chose. J’utilise quand même la touche F4 pour m’assurer que je n’ai pas commis d’erreur...
Pour éviter les lourdeurs, je renomme carrément en « id_client » les id_utilisateur et CLI_id_utilisateur valant pour les clients. De la même façon, je renomme en id_admin ce qui peut l’être :
Un coup de F4 et je sauvegarde les modèles...
N.B. pour ne pas perdre inutilement du temps, vous pouvez passer directement du MCD au MPD (qui pour moi est un MLD du moins graphiquement parlant, car le vrai MPD concerne les index et toute ces sortes de choses, dans la soute SQL).
Doit-on s’intéresser au script de création des tables ?
J'espère qu'il n'y a pas trop d'erreurs de copier/coller (et n'oubliez pas de voter pour les messages qui vous ont aidé...)
Partager