C'est le choix par défaut : "Texte variable"
Version imprimable
Super, j'ai corrigé.
voici :
Pièce jointe 564140
Bonsoir à tous et merci pour vos différents retours qui m'ont bien aidé à avancer sur ce projet.
:fleche: Le modèle vous semble abouti pour continuer ?
:merci: et bonne soirée
Bonjour Malick
Oui c'est conforme aux échanges qui précèdent
À+ :)
Bonjour Malick,
Ce dernier modèle prend bien en compte toutes les discussions.
Je fais confiance à mes collègues sur la validité de la conception. J'ai pour ma part quelques recommandations de forme :
- Concernant les types, dès lors que la longueur n'est pas clairement connue (nom, libellé, ...), il vaut mieux privilégier le VARCHAR.
- Pour le nom des rubriques, hors identifiant, il n'est pas forcément indispensable de reprendre le nom de la classe : pour les requêtes SQL, on préfixera les rubriques avec ce nom (ex : Projet.Nom).
- Je préfère éviter le tout-majuscules pour le nom des tables pour mieux mettre en valeur les mots clé SQL (mais ça, c'est une question de goût !)
- Enfin, j'aime bien les modèles "bien alignés" ! :mouarf:
Donc, voici comment je verrai ce modèle :
Pièce jointe 564414
Bonne continuation ! :lol:
Bonjour,
:fleche: Merci escartefigue pour les conseils :ccool:
:fleche: Merci également à CinePhil :ccool:
:fleche: Merci Paprick, j'intègre vos remarques relatives à la forme dans la version et conformément à ton modèle. :ccool:
Je passe le fil en :resolu:
:merci: et bonne semaine
Malick
Bonjour,
J'ai commencé à développer l'application et je me rend compte que deux règles m'avaient échappées :aie:
- R1 : un projet comporte plusieurs phases (Phase 1, Phase 2 etc.)
- R2 : un montant tiré (Entité Tirage) est réparti sur les différentes Phases (on peut l'avoir sur uniquement une seule phase).
J'ai essayé de les intégrer dans mon modèle. Qu'en pensez-vous ?
Pièce jointe 567393
Merci d'avance encore
Salut !
Sur le pur plan de la modélisation, tu as un effet de boucle : Un tirage peut être réparti sur une phase d'un projet associer à un emprunt qui n'est pas celui du tirage. :aie:
De plus, je suis étonné qu'une phase puisse faire partie de plusieurs projets ! 8O
Tes règles de gestion restent imprécises car il manque la contraposée :
R1 : un projet comporte plusieurs phases et une phase est comprise dans un (à plusieurs ?) projets.
R2 : un montant tiré (Entité Tirage) est réparti sur les différentes Phases et une phase est répartie en un à plusieurs tirages ?
A mon avis :
R1 : Un projet est découpé en une à plusieurs phases et une phase est un découpage d'un seul projet.
R2 : Un tirage finance une à plusieurs phases et une phase est financée par un à plusieurs tirages.
Comment éviter l'effet de boucle décrit plus haut ?
1) Commençons par considérer que la phase est un morceau du projet et ne peut pas exister sans lui et utilisons en conséquence l'identification relative :
Projet -1,n----découper----(1,1)- Phase
=> L'identifiant du projet fera partie de la clé primaire de la table des phases.
Phase (Id_Projet, numeroPhase, Description)
2) Consiédrons aussi qu'un emprunt n'a pas de sens s'il n'est pas associé à un projet et utilisons de même l'identification relative :
Projet -0,n----associer----(1,1)- Emprunt
=> L'identifiant du projet fera partie de la clé primaire de la table des emprunts.
Emprunt (Id_Projet, Id_Emprunt, dateE, montant, tauxInteretAnnuel, duree)
3) Comme nous avons déjà logiquement une identification relative du Tirage par rapport à l'emprunt qui le comprend, l'identifiant du projet fera partie de la clé primaire de la table des tirages.
Tirage (Id_Projet, Id_Emprunt, numeroTirage, reference, dateDemande, montant)
4) La clé primaire de la table associative représentant l'association "Répartir" sera composée des colonnes référençant la phase (donc le couple {Id_Projet, numeroPhase}) et référençant le tirage (donc le triplet {Id_Projet, Id_Emprunt, numeroTirage}). L'Id_projet ne sera dans la table associative qu'une seule colonne qui sera dans les deux références et référencera donc le même projet. L'effet de boucle est ainsi cassé : le projet du tirage sera bien le même que celui de la phase. :lun:
Repartir (Id_Projet, Id_Emprunt, numeroTirage, numeroPhase...)
Salut Cinephil,
:fleche: Effectivement tes remarques sont très correctes, et tu as bien compris ma problématique :king:Citation:
A mon avis :
R1 : Un projet est découpé en une à plusieurs phases et une phase est un découpage d'un seul projet.
R2 : Un tirage finance une à plusieurs phases et une phase est financée par un à plusieurs tirages.
Je vais mettre en application tes propositions et fournir le modèle mis à jour.
Merci bien.
Bonne soirée
Salut CinePhil,
Voici le modèle corrigé.
Pièce jointe 567588
Juste une question : dans l'association Financer, l'attribut FKId_Projet_1 ne pose-t-il pas de soucis ? sachant que c'est le même que FKId_Projet.
Preteur = (Id_Preteur COUNTER, nom CHAR(50), compte BYTE);
Projet = (Id_Projet COUNTER, nom VARCHAR(10));
Devise = (Id_Devise COUNTER, Libelle VARCHAR(10), code CHAR(3), dateDebut DATE, dateFin DATE);
Phase = (#FKId_Projet, numeroPhase VARCHAR(10), Description VARCHAR(10));
Emprunt = (#FKId_Projet, Id_Emprunt COUNTER, dateE DATE, montant CURRENCY, tauxInteretAnnuel DECIMAL(5,3), duree BYTE, #FKId_Devise);
Tirage = (#(#FKId_Projet, FKId_Emprunt), numeroTirage BYTE, reference VARCHAR(30), dateDemande DATE, montant CURRENCY);
octroyer = (#FKId_Preteur, #(#(#FKId_Projet, FKId_Emprunt), FKnumeroTirage), datePaiementTirage DATE);
Financer = (#(#(#FKId_Projet, FKId_Emprunt), FKnumeroTirage), #(#FKId_Projet_1, FKnumeroPhase));
Merci d'avance et bonne soirée
Malick
Je choisirais plutôt du VARCHAR pour le nom. Les noms vont-ils tous faire 50 caractères ?Citation:
Preteur = (Id_Preteur COUNTER, nom CHAR(50), compte BYTE);
Le compte ne sera compris qu'entre 0 et 255 ?
Là par contre, si les noms ne dépassent jamais 10 caractères, je choisirais plutôt du CHAR, à plus forte raison s'ils font tous 10 caractères.Citation:
Projet = (Id_Projet COUNTER, nom VARCHAR(10));
Le "Franc Suisse", par exemple, fait plus de 10 caractères.Citation:
Devise = (Id_Devise COUNTER, Libelle VARCHAR(10), code CHAR(3), dateDebut DATE, dateFin DATE);
Il doit être possible de trouver quelque part une table de référence de toutes les devises et l'utiliser tel quel ou bien l'importer et chercher quelle est la taille maxi du plus long nom pour calibrer ta colonne.
De quelle forme va être le numéro de phase pour justifier le choix du VARCHAR(10) ? Si c'est justifié, un CHAR(10) serait probablement mieux. Et j'aurais plutôt choisi un type entier court.Citation:
Phase = (#FKId_Projet, numeroPhase VARCHAR(10), Description VARCHAR(10));
Par contre, une description en 10 caractères maxi, ça me semble bien court !
VARCHAR(30) pour la référence, n'est-ce pas un peu long ?Citation:
Tirage = (#(#FKId_Projet, FKId_Emprunt), numeroTirage BYTE, reference VARCHAR(30), dateDemande DATE, montant CURRENCY);
Si c'est le logiciel de modélisation qui a généré ça automatiquement, il faut alors corriger à la main pour ne conserver qu'une colonne pour l'id_Projet. Oui, une colonne peut faire partie de plusieurs clés étrangères.Citation:
Financer = (#(#(#FKId_Projet, FKId_Emprunt), FKnumeroTirage), #(#FKId_Projet_1, FKnumeroPhase));
Juste une question : dans l'association Financer, l'attribut FKId_Projet_1 ne pose-t-il pas de soucis ? sachant que c'est le même que FKId_Projet.
Bonjour,
Tout à fait d'accord. Et pour le compte, il serait peut-être plus prudent de prévoir un SMALLINT (16 bits) ou un INT (32 bits).
D'accord également. Mais je pense que le nom du projet mérite aussi un VARCHAR(50).Citation:
Là par contre, si les noms ne dépassent jamais 10 caractères, je choisirais plutôt du CHAR, à plus forte raison s'ils font tous 10 caractères.
:plusser:Citation:
Le "Franc Suisse", par exemple, fait plus de 10 caractères.
Il doit être possible de trouver quelque part une table de référence de toutes les devises et l'utiliser tel quel ou bien l'importer et chercher quelle est la taille maxi du plus long nom pour calibrer ta colonne.
Oui : SMALLINT pour le numéro de phase et un VARCHAR(50) pour la description.Citation:
De quelle forme va être le numéro de phase pour justifier le choix du VARCHAR(10) ? Si c'est justifié, un CHAR(10) serait probablement mieux. Et j'aurais plutôt choisi un type entier court.
Par contre, une description en 10 caractères maxi, ça me semble bien court !
C'est l'aspect qui me gêne le plus... Effectivement, le logiciel génère ça puisque les clé étrangères sont issues de deux classes d'entités différentes. Le problème c'est que le MCD ne dit pas explicitement que cet identifiant de projet doit être le même : or, c'est la base de la solution proposée par Philippe, solution qui est la bonne mais qui nécessite que le DBA vienne préciser la conception (en retirant FKId_PRojet_1, et en assurant ensuite les jointures vers les deux tables avec le seul et unique FKId_Projet).Citation:
Si c'est le logiciel de modélisation qui a généré ça automatiquement, il faut alors corriger à la main pour ne conserver qu'une colonne pour l'id_Projet. Oui, une colonne peut faire partie de plusieurs clés étrangères.
J'entrevois 2 solutions à cette situation : la première consiste à laisser les 2 FKId_Projet et faire un CHECK pour s'assurer de leur égalité... bon, pas terrible :weird: ; le deuxième, consiste à rajouter des ALTER TABLE pour annuler la clé primaire de "Financer" générée initialement, dropper FKId_Projet_1 et recréer la bonne clé... Lourd, mais ça marche.
Dans les deux cas, il suffit de rajouter une règle dans Looping avec le code SQL qui va bien : l'avantage de le laisser faire à Looping, c'est que le MCD exprimera la contrainte et restera conforme au schéma relationnel correspondant.
Salut CinePhil et Paprick,
Merci pour vos remarques et corrections :ccool:
:fleche: j'ai mis VARCHAR (30) pour le nom en attendant une validation. Sinon pour la taille, elle est variable en fonction des prêteurs, et je pense que 30 est abordable. Non ?
:fleche: Pour les devises, en parcourant ce site, je pense que 30 ou 50 serait bon. En applicatif, je pourrais abréger parfois si nécessaire.
:fleche: Cela m'a échappé, car les numéro de phase seront numérique. Je peux même les mettre en auto-incrément, car seul les libellés (Phase 1, Phase 2 seront importants). Qu'en penses-tu ?
Pour la description, ce sera Phase 1, Phase 2, etc.
:fleche:Cela me semble bon, car de ce que j'ai actuellement, on peut avoir Ref : BANQUE/DEMANDE TIRAGE/N°00023
:fleche: Ok donc je supprime juste FKId_Projet_1 et ce sera chose faite ? Je regarderai également la proposition de Paprick, mais avec le SQL à intégrer :aie:
Voici avec les corrections en attendant l'avis sur le dernier point relatif à la suppression de FKId_Projet_1 :
Pièce jointe 567748
Bonsoir,
Attention, l'auto-incrémentation ne se réinitialisera pas à chaque projet : le numéro de phase va continuer à s'incrémenter et représente donc un identifiant à lui tout seul. Rajouter l'identifiant relatif FKId_Projet revient alors à provoquer une sur-clé qui n'est donc pas minimale (pb d'irréductibilité) : ce n'est pas absolument interdit, mais ce n'est pas propre conceptuellement.
Je pense qu'il vaut mieux prendre un entier (un byte devrait suffire) : l'application devra se charger de gérer la numérotation des phases.
Salut,
Merci Paprick, j'ai corrigé pour mettre byte.
Sinon par rapport à ma question ici :
Citation:
Ok donc je supprime juste au niveau du script qui sera généré l'attribut FKId_Projet_1 et ce sera chose faite ? Je regarderai également la proposition de Paprick, mais avec le SQL à intégrer
Revenons sur la table associative "Financer" :
Personnellement et compte tenu de ma norme de nommage, inspirée de celle de SQLPro, elle s'appellerait par exemple tj_tir_financer_phs_tfp :Citation:
Financer = (#(#(#FKId_Projet, FKId_Emprunt), FKnumeroTirage), #(#FKId_Projet_1, FKnumeroPhase));
- tj pour "table de jointure" (ça pourrait être ta pour "table associative, comme j'ai plutôt tendance à les appeler, mais ce code est réservé aux "tables d'administration") ;
- tir pour "tirage" (la table des tirages s'appellerait chez moi te_tirage_tir) ;
- financer, simplement pour le nom de l'association ;
- phs pour phase (la table des phases s'appellerait chez moi te_phase_phs ;
- tfp reprend les initiales des trois termes utilisés dans le nom de la table tir_financer_phs.
Ce dernier trigramme serait chez moi repris en initiale du nom des colonnes et dans le nom des contraintes. Ça donnerait donc chez moi la table suivante :
tj_tir_financer_phs_tfp (tfp_id_projet, tfp_id_emprunt, tfp_numero_tirage, tfp_numero_phase)
La clé primaire est soulignée et les colonnes participant à une clé étrangère sont en italique (toutes, donc).
Les clés étrangères de cette tables seraient faites ainsi :
Code:
1
2 CONSTRAINT fk_tfp_tirage FOREIGN KEY (tfp_id_projet, tfp_id_emprunt, tfp_numero_tirage) REFERENCES te_tirage_tir (tir_id_projet, tir_id_emprunt, tir_numero_phase) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_tfp_phase FOREIGN KEY (tfp_id_projet, tfp_numero_phase) REFERENCES te_phase_phs (phs_id_projet, phs_numero_phase) ON DELETE CASCADE ON UPDATE CASCADE;
On voit bien qu'il n'y a qu'une seule colonne portant l'identifiant du projet mais cette colonne participe aux deux clés étrangères. Ainsi, on a supprimé l'effet de boucle du MCD : le projet du tirage est forcément le même que celui de la phase.
Nota :
Avec ces clés étrangères :
- la suppression d'un tirage entraîne automatiquement la suppression du financement mais pas la suppression de la phase ;
- la suppression d'une phase entraîne automatiquement la suppression du financement mais pas la suppression du tirage.
Idem pour les mises à jour (UPDATE)
S'il faut que phase et tirage soient supprimés en même temps, alors il faut procéder par procédure SQL. Sur un projet, j'ai essayé la solution du trigger AFTER DELETE mais sous MariaDB, les triggers ne se déclenchent pas sur action CASCADE d'une clé étrangère.
Salut CinePhil,
Tout d'abord merci pour tes remarques :ccool:
J'ai appliqué les corrections, à l'exception des contraintes ci-dessus dont je ne sais pas comment les intégrer via Looping :koi: Une idée sur comment le faire ?
Cela dit, après correction, j'ai ceci :
:fleche: FKtfp_Id_Projet_1 est toujours présent. Faut-il le laisser ou le supprimer anuellement donc ?Citation:
Preteur = (tfp_Id_Preteur COUNTER, tfp_nom VARCHAR(30), tfp_compte BYTE);
Projet = (tfp_Id_Projet COUNTER, tfp_nom VARCHAR(10));
Devise = (tfp_Id_Devise COUNTER, tfp_Libelle VARCHAR(30), tfp_code CHAR(3), tfp_dateDebut DATE, tfp_dateFin DATE);
Phase = (#FKtfp_Id_Projet, tfp_numeroPhase BYTE, tfp_Description VARCHAR(10));
Emprunt = (#FKtfp_Id_Projet, tfp_Id_Emprunt COUNTER, tfp_dateE DATE, tfp_montant CURRENCY, tfp_tauxInteretAnnuel DECIMAL(5,3), tfp_duree BYTE, #FKtfp_Id_Devise);
Tirage = (#(#FKtfp_Id_Projet, FKtfp_Id_Emprunt), tfp_numeroTirage BYTE, tfp_reference VARCHAR(30), tfp_dateDemande DATE, tfp_montant CURRENCY);
octroyer = (#FKtfp_Id_Preteur, #(#(#FKtfp_Id_Projet, FKtfp_Id_Emprunt), FKtfp_numeroTirage), tfp_datePaiementTirage DATE);
tj_tir_financer_phs_tfp = (#(#(#FKtfp_Id_Projet, FKtfp_Id_Emprunt), FKtfp_numeroTirage), #(#FKtfp_Id_Projet_1, FKtfp_numeroPhase));
Merci encore pour ton aide
Le spécialiste, car créateur, de Looping est Paprick. Pour autant que je sache, Looping, comme d'autres logiciels de modélisation, est capable de générer le code SQL de la base de données modélisée. Dans le cas de ton modèle, et si la composition des tables que tu donnes vient de Looping, il est possible que le code SQL pour la table financer comporte effectivement deux fois la colonne portant l'identifiant du projet. Il faut alors corriger le script SQL à la main avant de l'exécuter sur ton SGBD.Citation:
à l'exception des contraintes ci-dessus dont je ne sais pas comment les intégrer via Looping Une idée sur comment le faire ?
Tu n'es pas obligé d'adopter ma norme de nommage. Comme tes autres tables ont un nom simple (Preteur, Projet...), appelle donc simplement la table associative "Financer", par exemple. C'est d'ailleurs peut-être le nom que te proposera naturellement Looping (je ne l'ai pas encore assez exploré pour savoir s'il prend simplement le nom de l'association en nom de table).
Donc le code généré pourrait ressembler à ça :
Code:
1
2
3
4
5
6
7
8
9 CREATE TABLE Financer ( FK_id_projet INTEGER NOT NULL, FK_id_emprunt INTEGER NOT NULL, FK_numero_tirage TINYINT NOT NULL, FK_id_projet_1 INTEGER NOT NULL, FK_numero_phase TINYINT NOT NULL, CONSTRAINT FK_tirage FOREIGN KEY (FK_id_projet, FK_id_emprunt, FK_numero_tirage) REFERENCES Tirage (FK_id_projet, FK_id_emprunt, numero_tirage), CONSTRAINT FK_phase FOREIGN KEY (FK_id_projet_1, FK_numero_phase) REFERENCES Phase (FK_id_projet, numero_phase) );
Il faudrait alors le corriger à la main en retirant la colonne FK_id_projet_1 et en retirant "_1" de "FK_id_projet_1" à la FK_phase :
Code:
1
2
3
4
5
6
7
8 CREATE TABLE Financer ( FK_id_projet INTEGER NOT NULL, FK_id_emprunt INTEGER NOT NULL, FK_numero_tirage TINYINT NOT NULL, FK_numero_phase TINYINT NOT NULL, CONSTRAINT FK_tirage FOREIGN KEY (FK_id_projet, FK_id_emprunt, FK_numero_tirage) REFERENCES Tirage (FK_id_projet, FK_id_emprunt, numero_tirage), CONSTRAINT FK_phase FOREIGN KEY (FK_id_projet, FK_numero_phase) REFERENCES Phase (FK_id_projet, numero_phase) );
Effectivement ce que j'ai fourni provient directement de Looping.
Je vais donc corriger suivant tes indications et fournir le SQL intégral du projet. Je te reviens...
Merci et @+
Bonsoir,
Effectivement, je confirme que Looping génère 2 fois la colonne... et c'est malheureusement normal :calim2: : en effet, rien dans le MCD indique que FK_id_projet et FK_id_projet_1 concerne forcément un même projet... Je sais, c'est évident pour le concepteur et Philippe a entièrement raison de le traiter de cette manière, mais conceptuellement, ce n'est pas spécifié formellement.
Il y a donc deux solutions : modifier le code généré par Looping et supprimer FK_id_projet_1 comme le propose Philippe et tout marchera très bien ; l'autre solution, qui reviendra au même in fine, est de spécifier dans le MCD la suppression de ce doublon au sein d'une règle incluant le code SQL qui va bien (ALTER TABLE...) : de cette manière, le MCD sera en concordance avec le schéma relationnel. François (fsmrel) a déjà fait ce genre de manip.
C'est tout à fait ça : par défaut, pour les tables associatives, Looping reprend le nom de l'association, mais un nom logique différent peut aussi être affectée... Et, dans quelques jours Philippe, c'est là que tu pourras référencer des bases de données externes avec la version 2.6 de Looping :lol:.Citation:
Tu n'est pas obligé d'adopter ma norme de nommage. Comme tes autres tables ont un nom simple (Preteur, Projet...), appelle donc simplement la table associative "Financer", par exemple. C'est d'ailleurs peut-être le nom que te proposera naturellement Looping (je ne l'ai pas encore assez exploré pour savoir s'il prend simplement le nom de l'association en nom de table).