Abondance de biens ne nuit pas, au diable l'avarice ! Va pour le type d'entité ADREL (ou l'attribut du même nom dans l'en-tête de la table CONTACT... )
Abondance de biens ne nuit pas, au diable l'avarice ! Va pour le type d'entité ADREL (ou l'attribut du même nom dans l'en-tête de la table CONTACT... )
Bonjour à tous,
Je me permets de m'immiscer, juste pour cette dernière partie...
==> Fsmrel, sauf ton respect (tu le sais bien), si nous commençons à créer deux tables pour toutes les paires de cardinalités {1,1/1,1}, nous n'avons pas fini !... Pour {0,1/1,1}, cela se discute (voir cette discussion).Envoyé par Fsmrel
Kropernic, je ne peux que te recommander de garder sous le coude cette analyse exhaustive de toutes les combinaisons possibles de cardinalités qui t'aidera dans tes décisions de création de tables.
Je ne créerais pas, moi non plus, d'entité type pour l'adrel puisque la MOA dit qu'il n'y a qu'une seule adrel par contact. C'est donc une propriété du de l'entité type contact et non pas une entité type ayant sa vie propre.
Bien entendu, mais je vous ferai observer que j’ai écrit à Kropernic que j’avais pas mal de choses à dire sur le sujet et votre intervention fait que vous embrouillez tout. Du point de vue de la théorie relationnelle, le temps et l’espace ne sont pas à prendre en considération, mais seulement le Quoi. Vous sautez à pieds joints dans l’étape d’« optimisation » (comme nous le faisons tous inconsciemment du reste). Autant dire aux mathématiciens qu’avec la bijection on n’en a pas fini, autant la zapper. En me citant vous avez effacé une partie importante, celle où je fais mention de la théorie : en effet, avant de foncer dans le côté pratique des choses, il faut examiner le côté théorique.
J’aimerais donc reprendre le cours normal de la discussion avec Kropernic, sans sauter les étapes, mais si je dis quelque chose qui est en contradiction avec la théorie, il va sans dire que toute objection sera la bienvenue.
P.-S. Pour le moment on est en quelque dans le cadre du Modèle binaire, voyez NIAM à ce propos.
, effectivement, ça se tient, Fsmrel...
Bonsoir,
Je disais donc : examinons les conséquences de la mise en oeuvre d’une paire de tables CONTACT / ADREL (le terme ADREL employé par CinePhil a l’avantage de la concision : deux syllabes ).
Faisons fi des aspects psychologiques et sentimentaux¹. Du point de vue de la théorie relationnelle, on écrit :
1) Pour la relvar CONTACT (relvar est l’abréviation de relational variable) :
1) Pour la relvar ADREL :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 VAR CONTACT BASE RELATION { ContactId ContactId , ContactNom CHAR , AdrelId AdrelId , ... } KEY {ContactId} KEY {AdRelId} FOREIGN KEY {AdRelId} REFERENCES ADREL ;
Où le couple <ContactId ContactId> désigne un attribut de l’en-tête de la relvar ; le 1er élément "ContactId" est le nom de l’attribut et le 2e élément "ContactId" son type (qui pourrait très bien être autre, par exemple INTEGER, mais je ne vois pas pourquoi on effectuerait des opérations arithmétiques ayant des identifiants pour opérandes, l'opérateur « = » suffit largement).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 VAR ADREL BASE RELATION { AdrelId AdrelId , AdrelLibelle CHAR , ContactId ContactId , ... } KEY {AdRelId} KEY {ContactId} FOREIGN KEY {ContactId} REFERENCES CONTACT ;
2) Traduction en SQL :
Table CONTACT :
Table ADREL :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE CONTACT ( ContactId INTEGER NOT NULL , ContactNom VARCHAR(64) NOT NULL , AdrelId INTEGER NOT NULL , ... , PRIMARY KEY (ContactId) , UNIQUE (AdRelId) , FOREIGN KEY (AdRelId) REFERENCES ADREL ) ;
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE ADREL ( AdrelId INTEGER NOT NULL , AdrelLibelle VARCHAR(64) NOT NULL , ContactId INTEGER NOT NULL , ... , PRIMARY KEY (AdRelId) , UNIQUE (ContactId) , FOREIGN KEY (ContactId) REFERENCES CONTACT ) ;
Se pose maintenant le problème de la création d’un contact et de celle de son adresse électronique.
En relationnel, pas de problème, on procède par affectation multiple :
Les deux inserts font partie de la même instruction, ils y sont simplement séparés par une virgule. La fin de l’instruction est marquée par un point-virgule.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 INSERT CONTACT RELATION {TUPLE {ContactId ContactId(123), ContactNom 'Kropernic', AdrelId 314, ... } } , INSERT ADREL RELATION {TUPLE {ContactId ContactId(123), AdrelLibelle 'Biglotron.dvp', AdrelId 314, ... } } ;
Vous noterez en passant que l’attribut ContactId figure (pourquoi pas ?) en 1re position dans le 2e insert : en effet, en relationnel l’ordre des attributs ne joue aucun rôle. Comme disait le maître de philosophie de Monsieur Jourdain : « Mourir vos beaux yeux, belle Marquise, d'amour me font. »
Avec SQL Server, les choses se gâtent : l’affectation multiple n’est pas prévue et les contrôles son immédiats : on est donc aux prises avec le dilemme de l’œuf et de la poule : si l’on cherche à insérer le contact Kropernic, le SGBD refusera au motif que l’intégrité référentielle serait violée, l’adresse électronique du susdit devant déjà être présente, et réciproquement. Le gougnafier vous dira : « Supprimons les contraintes référentielles ! », mais nous sommes ici entre gens sérieux. Supprimons peut-être de la table CONTACT l’attribut AdrelId et la contrainte référentielle qui va avec ? Mais alors on peut créer le contact Kropernic et oublier ad infinitum de le doter de son adresse électronique, en violation de la règle de gestion (tamponnée) selon laquelle tout contact a exactement une adresse électronique.
On sera conduit à se rabattre sur une solution permettant que la règle tamponnée soit respectée, consistant par exemple à ce que la table CONTACT absorbe la table ADREL :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE CONTACT ( ContactId INTEGER NOT NULL , ContactNom VARCHAR(64) NOT NULL , AdrelId INTEGER NOT NULL , AdrelLibelle VARCHAR(64) NOT NULL , ... , PRIMARY KEY (ContactId) , UNIQUE (AdRelId) ) ;
Maintenant, suite à l'unification des tables, si la Production se plaint de certains effets secondaires fâcheux (suite par exemple à la pose de verrous intempestifs à l’occasion de modifications à tout va des adresses électroniques, pendant que dans le même temps de nombreux utilisateurs cherchent à consulter la partie contact), tant pis pour elle, elle n’aura plus qu’à implorer la MOA de revoir la règle de gestion en sorte que celle-ci soit ainsi modifiée : « un contact peut ne pas avoir d’adresse électronique », mais, Sahib, ceci est une autre histoire.
Kropernic, vous pouvez donc conceptuellement représenter les contacts et les adresses selon votre bon plaisir, mais quand il faudra passer à la concrétisation de la base de données, je crains que vous ne soyez obligé de vous plier au contraintes de SQL Server qui ne permet pas aujourd’hui d’effectuer des affectations multiples.
Une échappatoire quand même : Si vous tenez à tout prix à conserver les deux tables CONTACT et ADREL, vous pouvez définir une vue qui en soit la jointure, interdire (par REVOKE) les mises à jour directe de ces tables, et donc imposer qu’elles ne portent que sur la vue : c’est un trigger qui ventilera alors les données dans les deux tables lors des inserts. Ne pas oublier les triggers pour les suppressions et modifications (cf. ci-dessous). C’est une solution pour éliminer les effets de bord et prévoir les changements qui pourraient être imposés plus tard par la MOA : « M. Kropernic, nous avons désormais besoin de connaître les différentes adresses électroniques des contacts, merci d'adapter au plus vite votre système, c'est urgent. » Il est clair que si les deux tables ont été fondues en une seule, alors celle-ci devra faire l’objet d’une scissiparité...
Et pourquoi pas l’inverse ? Le contact n’étant alors qu’un attribut de l’adresse ?
Il y a une trentaine d’années, lors de l’étape de conception j’ai fait plier un DSI pour qui le contrat était une propriété du client, car il raisonnait en commercial, auquel cas, émotionnellement parlant, c’est le client qui avait de l’importance. Il avait simplement oublié que grâce aux traitements « batch de nuit » on faisait rentrer les sous (un batch en retard c’est des sous en moins), et c’est alors le contrat (en fait le compte-client) qui jouait le rôle déterminant.
_____
¹ Une anecdote...
Je me souviens des soucis qu’avait le concepteur d’un MCD Merise dans une banque (il n'en avait pas dormi de la nuit quand il m'en parla). Il avait modélisé une opération sur titre comme une association entre un titre, un trader, un broker, une place cotation, etc. Tout allait bien. Hélas ! l’utilisateur (de la MOA/MOE) qui se piquait de connaître la modélisation avait exigé que cette opération fasse l’objet d’une entité-type. J’ai expliqué au concepteur que le client était roi et qu’il fallait se plier à sa vision des choses. En effet, que l’opération soit représentée sous forme d’un carré ou d’un rond (ou un carond ), peu importe, car après dérivation on produisait en l'occurrence une table et le résultat était strictement le même. Au fait, pourquoi l’utilisateur avait-il exigé que l’opération sur titre fasse l’objet d’une entité-type ? Tout simplement pour des raisons strictement émotionnelles, car à l’époque, les titres furent dématérialisés, les papiers réduits à l’état de confettis ou de cendres, mais l’utilisateur en manque sentait toujours son carnet à souches dans sa poche, tel une entité bien concrète, et ça lui faisait toujours mal de ne plus le sentir, un peu comme le manchot a mal à son bras manquant...
Bonjour à tous,
==> hum... un peu choquant, tout de même (au risque d'embrouiller tout de nouveau, désolé).Envoyé par Fsmrel
En effet, à l'avenir, il y plus de chance de faire évoluer l'application côté Contact que côté Adrel. En clair, il y a plus de chance de créer des entités associées à l'entité Contact que de créer des entités associées à l'entité Adrel.
Tout est relatif. Supposons que le demandeur soit le patron du réseau pour cette partie du modèle : c’est peut-être l’adresse qui l'intéresse, plus que ce qu’il y a derrière, à savoir la personne qui y est rattachée.
Dans l’univers du discours proposé par Kropernic, c’est évident, d’où la remarque figurant mon message précédent :
« M. Kropernic, nous avons désormais besoin de connaître les différentes adresses électroniques des contacts, merci d'adapter au plus vite votre système, c'est urgent. »Notons en passant que dans le système kropernicien (où normalement tout tourne rond autour du soleil Gift !) il est modélisé ceci :
[Téléphone]----1,1----(R)----0,N----[Client]Mais, pour changer d’univers, je consulte maintenant l’annuaire téléphonique de ma propre entreprise et que constaté-je ? Simplement qu’une personne est appelable en direct seulement à un numéro de téléphone et qu’un numéro de téléphone est utilisable pour appeler directement au moins une personne (bref, on est quelques uns dans le même bureau, à se partager un unique téléphone) :
[Téléphone]----1,N----(R)----1,1----[Personne]
A part des choses du genre 1 < 10 en arithmétique, on peut dire que rien n’est jamais définitif dans ce f... métier de concepteur, comme dans celui d’astronome. Il n’y a pas qu’une vérité car en des lieux ou des temps différents celle-ci est changeante : en fonction des dernières idées de la MOA dans le cas de Kropernic, en fonction des décisions du comité qui va bien dans le cas de l’astronome, ainsi, par exemple, pendant quelques décennies Pluton fut la 9e planète mais elle a perdu ce statut...
Relativisons, disais-je. Si l’on se place d’un point de vue spatial, comme disait l’ami Blaise : « Vérité en deçà des Pyrénées, erreur au-delà. », ou, bien avant lui, le camarade Michel de Montaigne : « Quelle vérité est ce que ces montaignes bornent, mensonge au monde qui se tient au delà ? »
Si l’on se place d’un point de vue temporel : pendant plus de deux mille ans la thèse du géocentrisme prévalut (Aristote, Ptolémée), jusqu’à ce qu’un certain astronome polonais put démontrer que l’héliocentrisme était plus cohérent. Que nous réserve l’avenir ?
Dans cette échappatoire, j’ai omis de préciser qu’une des deux clés étrangères doit sauter, sinon avec SQL Server on serait confronté au problème de l’œuf et de la poule.
A titre d’exemple, on pourrait utiliser les structures suivantes pour les tables (celle de la table ADREL restant en fait inchangée) :
Table CONTACT :
Table ADREL :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 CREATE TABLE CONTACT ( ContactId INTEGER NOT NULL , ContactNom VARCHAR(64) NOT NULL , ... , PRIMARY KEY (ContactId) ) ;
L’utilisateur ne doit utiliser que la vue. Appelons-la par exemple CONTACT_ADREL. Elle serait ainsi définie :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE ADREL ( AdrelId INTEGER NOT NULL , AdrelLibelle VARCHAR(64) NOT NULL , ContactId INTEGER NOT NULL , ... , PRIMARY KEY (AdRelId) , UNIQUE (ContactId) , FOREIGN KEY (ContactId) REFERENCES CONTACT ON DELETE CASCADE ) ;
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 CREATE VIEW CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle, ...) AS SELECT x.ContactId, x.ContactNom, y.AdrelId, y.AdrelLibelle, ... FROM CONTACT AS x JOIN ADREL AS y ON x.ContactId = y.ContactId ;
Avec cette vue, l’utilisateur a ce qui lui faut pour les consultations.
En ce qui concerne les INSERT portant sur la « table » CONTACT_ADREL : SQL Server n’étant pas à niveau par rapport à la norme SQL puisqu’il n’autorise pas les inserts « dans » les vues de jointure, c’est le trigger ad-hoc qui ventile les données dans les tables CONTACT et ADREL.
Pour des DELETE : le trigger utilisé à cet effet pourra se contenter de procéder à un delete portant seulement sur la table CONTACT, car la clé étrangère permettant de la référencer à partir de la table ADREL est porteuse ici d’une clause ON DELETE CASCADE, faisant que le SGBD propage la suppression dans la table ADREL.
Pour les UPDATE : par trigger, on s’assurera que les modifications n’affectent pas les clés primaires, puisqu’elles n’ont aucune raison de l’être (du fait de l’utilisation des auto-incréments non significatifs pas vocation, et chers à CinePhil). Pour la colonne ContactId de la table ADREL, je ne vois pas a priori de raison de rejeter l'update.
Je prendrai le temps de vérifier que tout cela fonctionne.
Quel plaisir de lire vos messages plein de bons sens en ce lundi matin en arrivant au bureau. Cela remet de meilleure humeur après une heure de trajet dans un train bondé.
Un grand merci !
Bonsoir le(s) voyageur(s),
Symétrie ou complétude obligent, après l’aller il y a le retour... Le train est-il aussi bondé le soir ?
Reprenons les tables suivantes :
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 CONTACT ( ContactId INTEGER NOT NULL , ContactNom VARCHAR(64) NOT NULL , PRIMARY KEY (ContactId) ) ; CREATE TABLE ADREL ( AdrelId INTEGER NOT NULL , AdrelLibelle VARCHAR(64) NOT NULL , ContactId INTEGER NOT NULL , PRIMARY KEY (AdRelId) , UNIQUE (ContactId) , FOREIGN KEY (ContactId) REFERENCES CONTACT ON DELETE CASCADE ) ;
Ainsi que la vue :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 CREATE VIEW CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) AS SELECT x.ContactId, x.ContactNom, y.AdrelId, y.AdrelLibelle FROM CONTACT AS x JOIN ADREL AS y ON x.ContactId = y.ContactId ;
Un trigger pour les INSERT portant sur la vue et chargé de répercuter dans les tables peut être le suivant :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 CREATE TRIGGER CONTACT_ADREL_INSERT_TR ON CONTACT_ADREL INSTEAD OF INSERT AS INSERT INTO CONTACT (ContactId, ContactNom) SELECT ContactId, ContactNom FROM INSERTED ; INSERT INTO ADREL (ContactId, AdrelId, AdrelLibelle) SELECT ContactId, AdrelId, AdrelLibelle FROM INSERTED ;
Un trigger pour les DELETE :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 CREATE TRIGGER CONTACT_ADREL_DELETE_TR ON CONTACT_ADREL INSTEAD OF DELETE AS DELETE FROM CONTACT WHERE ContactId IN (SELECT ContactId FROM DELETED) ;
Un trigger pour les UPDATE :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 CREATE TRIGGER CONTACT_ADREL_UPDATE_TR ON CONTACT_ADREL INSTEAD OF UPDATE AS IF UPDATE (ContactId) OR UPDATE (AdrelId) BEGIN RAISERROR ('On ne touche pas aux clés primaires !', 16, 1) ROLLBACK TRAN RETURN END IF UPDATE (ContactNom) UPDATE CONTACT SET ContactNom = (SELECT DISTINCT INSERTED.ContactNom FROM INSERTED) WHERE ContactId IN (SELECT CONTACT.ContactId FROM DELETED JOIN CONTACT ON CONTACT.ContactId = DELETED.ContactId) ; IF UPDATE (AdrelLibelle) UPDATE ADREL SET AdrelLibelle = (SELECT DISTINCT INSERTED.AdrelLibelle FROM INSERTED) WHERE AdrelId IN (SELECT ADREL.AdrelId FROM DELETED JOIN ADREL ON ADREL.AdrelId = DELETED.AdrelId) ;
Un zest de soupçon de début de jeu d’essai :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (1, 'Kropernic', 1, 'Kropernic@Pluton.com') ; INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (2, 'Kralilée', 2, 'Kralilée@Pluton.com') ; INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (3, 'Hubble', 3, 'Hubble@Terre.com') ; INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (4, 'Leverrier', 4, 'Leverrier@Terre.com') ; INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (5, 'Kropernic', 5, 'Leverrier2@Terre.com') ; INSERT INTO CONTACT_ADREL (ContactId, ContactNom, AdrelId, AdrelLibelle) VALUES (6, 'Newton', 6, 'Isaac@Newton.org') ; SELECT '' AS 'CONTACT', * FROM CONTACT ; SELECT '' AS 'ADREL', * FROM ADREL ; SELECT '' AS 'CONTACT_ADREL', * FROM CONTACT_ADREL ; UPDATE CONTACT_ADREL SET ContactNom = 'Inconnu' , AdrelLibelle = 'xxx@yyy.zz' WHERE ContactId IN (1, 2, 5) ; SELECT '' AS 'CONTACT_ADREL', * FROM CONTACT_ADREL ; UPDATE CONTACT_ADREL SET AdrelLibelle = 'aaa@bbb.cc' WHERE ContactId IN (1, 5) ; SELECT '' AS 'CONTACT_ADREL', * FROM CONTACT_ADREL ; DELETE FROM CONTACT_ADREL WHERE ContactId = 5 OR AdrelLibelle LIKE '%Terre.com%' ; SELECT '' AS 'CONTACT_ADREL', * FROM CONTACT_ADREL ; DELETE FROM CONTACT_ADREL ; SELECT '' AS 'CONTACT_ADREL', * FROM CONTACT_ADREL ;
Aux erreurs de copier/coller près, en espérant que tout cela fonctionne avec un jeu d’essai plus complet.
Le retour était plus agréable. Merci de vous en inquiéter. C'est surtout que ce matin, à cause de retards, il y avait la foule de 2 trains dans un seul... Je crois que vous avez le même genre de soucis avec la SNCF non ?
Pour ce qui est trigger sur les vues de jointures, je "maitrise" (connaître serait probablement un meilleur terme cela dit) le sujet pour l'avoir déjà pratiqué.
Bref, je crois que j’approche du but... En tout cas, à moins que mon collègue puisse utiliser à son tour la version d'essai, je vais être obligé de finaliser demain ^^.
Sur ce, je vous souhaite une bonne soirée à vous dit à demain.
Salut les merisiens !
Nouvelle journée et donc, nouvelles informations !
Nouvelles informations qui ne viennent pas de la MOA (j'appelle MOA le service qui utilisera l'application) mais de notre maison mère en Allemagne.
En fait, des données tirées de la DB que je conçois actuellement devront être envoyées vers l'Allemagne dans un futur relativement proche. Et il se trouve qu'ils ont besoin d'une info que je n'avais pas prise en compte jusqu'ici car non-significative pour nous.
Tout ça pour illustrer ma réponse à fsmrel lorsqu'il a évoqué pour la première fois la MOA et que je lui avais répondu : "Il n'y a pas vraiment de MOA bien définie".
Bref, ce qu'ils demandent n'est pas compliqué du tout. Je pense même déjà savoir comment faire. Je veux juste savoir si on a le droit de faire ce genre de chose (je ne vois pas ce qui l'interdirait mais bon...) :
Où A est l'entité-type GIFT, B est l'entité-type CARD et C serait une nouvelle entité-type GIFT_LIST_CARD qui représentera les cartes de gift-list (carte de liste de cadeaux en français mais j'utilise le jargon interne).
Code : Sélectionner tout - Visualiser dans une fenêtre à part A<--hérite---B<--hérite---C
Une gift-list-card étant une gift-card normale pour nous, pour les allemands, le montant qu'elle reçoit est divisé en 2 sous-montant. Je pense donc faire hérité cette entité de l'entité CARD (gift-card normale) et ajouté les attributs propres.
Cela me propre propre et net de cette façon.
Bonjour,
Disons, pour faire vite, qu'il en est ainsi depuis que l’on n’a plus les locomotives à vapeur (même chose pour le respect des horaires...)
Quelques remarques concernant votre MCD (version du 20/09/2012)
Type d’entité STORE
Comme je l’ai signalé dans le message #51, le code du magasin doit faire l’objet d’une clé alternative. Relisez à ce sujet ce post à l’attention de Petit Rasta, où je cite le grand Yves Tabourier, celui a qui a traversé le miroir. Vous trouverez dans ce message la façon de définir une clé alternative, ce qui n’est pas intuitif avec PowerAMC, du moins avec la version que j’utilise, c'est-à-dire la V11. L’adaptation avec la V16 ne doit pas être compliquée, vous me le direz (mais peut-être savez-vous déjà comment faire).
Ce qu’on attend :
Cela vaut pour chaque type d’entité du MCD sujette à être dotée d’une clé alternative. Voyez par exemple le cas du type d’entité TRANSACTION :
Type d’entité COMMANDE
Selon la représentation ci-dessous, les commandes n’ont pas leur propre système de numérotation, défini par l’utilisateur. A vous de voir s’il faut définir un attribut ad-hoc, car la MOA n’a aucun pouvoir sur l’attribut CommandeId (auto-incrémenté, sinon CinePhil fulminera...)
Type d’entité FOURNISSEUR
Remarque analogue. Ne définissez-vous pas un code pour l’utilisateur ? Par exemple le Siret ou autre, genre codification imposée par la MOA...
Date de sortie du stock
Dans votre MCD, on ne voit pas la sortie des stocks. Je rappelle que vous pouvez modéliser cela ainsi (cf. message #53) :
Type d’entité DESTRUCTION (ou de préférence GIFT_DETRUIT)
Votre type d’entité DESTRUCTION est encore représenté ainsi :
Ce qui revient à dire qu’un Gift peut être détruit plusieurs fois : tel le phénix, il peut renaître de ses cendres... Puisqu'un gift ne meurt qu'une fois, comme je l’ai déjà signalé (cf. message #76) il faudrait utiliser une représentation correctement dérivable (alternative héritage / rôle dominant) :
La liste des observations n’est pas exhaustive, mais il serait bien que vous preniez déjà en compte ce qui précède.
J'ignorais comment faire et je n'avais pas jusqu'ici réfléchi aux implication que cela avait sur la base de données. J'ai testé le processus sur l'entité store avec succès. Les modifications sur les autres entités vont suivre.
On n'a pas signalé de numérotation spécifique mais connaissant les énergumènes, c'est fort probable qu'il y en ait une. Je leur poserai la question demain (car il n'y a déjà plus personne bien sûr). Il s'agit "juste" d'un attribut supplémentaire qui sera une clef alternative. Ce sera pris en compte.Type d’entité COMMANDE
La par contre, je suis quasi certains qu'ils fonctionnent avec le nom du fournisseur. En même temps, s'il y en a 3 différents, c'est beaucoup ^^.Type d’entité FOURNISSEUR
Remarque analogue. Ne définissez-vous pas un code pour l’utilisateur ? Par exemple le Siret ou autre, genre codification imposée par la MOA...
Là il doit y avoir un malentendu. Peut-être n'ai-je pas reposter une version plus récente du MCD car le mcd que j'ai sous les yeux correspond au vôtre (à moins qu'il y aurait une subtilité que je n'aurais pas vue).Date de sortie du stock
La cardinalité 0,N du côté de l'entité-type GIFT est en effet une erreur/un oubli. Quelles sont les implications si, plutot que d'effectuer un héritage comme vous le proposer, j'applique la cardinalité 0,1 du côté de l'entité-type GIFT car, en effet, un gift peut subir une destruction et une destruction est subie par un gift. (je viens de remplacer le verbe dans l'association).Type d’entité DESTRUCTION (ou de préférence GIFT_DETRUIT)
Votre type d’entité DESTRUCTION est encore représenté ainsi :
Ce qui revient à dire qu’un Gift peut être détruit plusieurs fois : tel le phénix, il peut renaître de ses cendres... Puisqu'un gift ne meurt qu'une fois, comme je l’ai déjà signalé (cf. message #76) il faudrait utiliser une représentation correctement dérivable (alternative héritage / rôle dominant) :
La règle de gestion me semble correct non ? Quels avantages/inconvénients pour ces deux modélisations différentes ?
Quand je pense que, sur les bancs de l'école, j'exécrais les parties d'analyse... Alors que maintenant, sûrement car je comprends enfin ce que je fais, je trouve cela passionnant !
Un grand merci !
Juste une petite question pour éclaircir un truc sur les clefs alternatives.
A quel niveau se définissent-t-elles ?
Dans le cas de l'entité-type STORE, pas de souci pour le faire au niveau du MCD.
Par contre, pour le cas de l'entité-type TRANSACTION, je ne peux, à priori, que le faire au niveau du MLD.
Le fait de définir des clefs alternatives pour identifier des objets me semble plus être un souci conceptuel que logique. Or le fait de ne pouvoir la définir que sur le MLD (car l'attribut du TYPE DE TRANSACTION n'est pas présent dans TRANSACTION au niveau du MCD) me chagrine un peu.
Bonsoir Bombardier Kropernic,
Bien entendu au niveau du MCD, mais, il est des situations dans lesquelles on ne peut agir qu’au niveau du MLD, par exemple quand on utilise l’identification relative.
Prenons l’exemple de l’identification de TRANSACTION relativement à GIFT :
[GIFT {GiftId, ...}]----0,N----(CONCERNER)----(1,1)----[TRANSACTION {TrnId, TrnDate, ...}]Identifier TRANSACTION relativement à GIFT revient, techniquement parlant, à tricoter l’association binaire CONCERNER et l’attribut TrnId qui joue le rôle d’identifiant relatif. Pour pouvoir mettre en œuvre une identification relative alternative « CONCERNER + TrnDate », il faudrait que PowerAMC soit étendu, ce qui techniquement ne poserait pas de problème, mais aujourd’hui on est coincé (je ne pense pas que la V16 ait apporté du nouveau à ce sujet, mais si vous trouvez quelque chose ès matière, merci de me le signaler...)
Conclusion : vous devrez procéder manuellement au niveau du MLD. Maintenant, comme je l’ai mentionné dans le post #76, vous pouvez sans risque virer l’attribut TRN_ID de l’entité-type TRANSACTION et utiliser TRN_DATE comme identifiant relatif (qu’Yves Tabourier me pardonne, une date c’est porteur de sens, mais bon...)
Remarque : Il est d'autres situations dans lesquelles PowerAMC est en l’occurrence impuissant, du fait par exemple (avec la notation Merise) du strict respect de la règle merisienne : « Une relation n’a pas d’identifiant propre », faisant que parfois on ne peut agir que sur le MLD, comme dans l’exemple des courses hippiques, où il ne faut pas qu’un jockey puisse monter plus d’un cheval dans la même course, et autres bizarreries qui ne valent que dans un monde quantique... En Merise on s’en sort théoriquement à coups de paquets de CIF, mais PowerAMC ne connaît pas. Certains n’ont pas hésité à s'asseoir sur la contrainte, à l’instar de Jean-Luc Hainaut (Université de Namur) avec DB-MAIN (AGL belge, yes Sir !), résolvant ainsi de façon simple et concise, cum digitos in nasum devrais-je dire, les problèmes posés par la contrainte merisienne. Voyez à ce sujet le MCD des courses hippiques correspondant.
La règle de gestion est correcte, ainsi bien sûr que la représentation suivante :
[GIFT]----0,1----CONCERNER----(1,1)----[GIFT_DETRUIT]Si j’ai proposé l’alternative de l’héritage, c’est simplement pour éviter d’avoir à supprimer manuellement la relation CONCERNER2 qui fiche la patouille dans le MLD (revoyez les posts #42, #76, #77) : une fois ça va, après on s’énerve... J’avais appelé ça « le subterfuge du feignant-qui-ne-veut-pas-bricoler-le-MLD ». Du reste, vous avez déjà utilisé ce subterfuge avec la relation d’héritage entre GIFT et GIFT_COMMANDE...
Il n’y a pas de quoi !
J'ai obtenu une promotion ?
J'ai finalement opté pour le subterfuge car, pour une raison que j'ignore, je n'arrivais pas à faire en sorte que la table DESTRUCTION du MLD reçoive l'attribut GFT_ID (provenant de la table GIFT). Bref, avec l'héritage, ça marche tout seul .La règle de gestion est correcte, ainsi bien sûr que la représentation suivante :[GIFT]----0,1----CONCERNER----(1,1)----[GIFT_DETRUIT]Si j’ai proposé l’alternative de l’héritage, c’est simplement pour éviter d’avoir à supprimer manuellement la relation CONCERNER2 qui fiche la patouille dans le MLD (revoyez les posts #42, #76, #77) : une fois ça va, après on s’énerve... J’avais appelé ça « le subterfuge du feignant-qui-ne-veut-pas-bricoler-le-MLD ». Du reste, vous avez déjà utilisé ce subterfuge avec la relation d’héritage entre GIFT et GIFT_COMMANDE...
Hello !
Ce coup, au niveau mcd, je pense bien que tout y est.
Par contre, j'ai des soucis techniques je pense...
Prenons l'exemple suivant :
Ce qui donne le MCD suivant :-Un gift commandé peut être concerné par une répartition et une répartition concerne un gift commandé.
-Une répartition est répartie (verbe à éventuellement changer) dans un magasin et un magasin peut avoir plusieurs répartition.
Ma question est : Pourquoi au niveau du MLD, l'entité REPARTITION ne récupère-t-elle pas l'identifiant de l'entité GIFT_COMMANDE ? (C'est ce qui est sensé passé quand même non ?)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 [REPARTITION]-1,1----CONCERNER----0,1-[GIFT_COMMANDE] | |1,1 | REPARTIR----0,N-[STORE]
Pas de problème par contre pour récupérer l'identifiant de l'entité STORE.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager