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

Modélisation Discussion :

MCD cycle relation 1,1


Sujet :

Modélisation

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut MCD cycle relation 1,1
    Bonsoir, j'aimerais un peu d'aide afin de résoudre mon petit problème.
    Un Ouvrier appartient à 1 et 1 seule équipe. Une équipe est composée d'ouvriers.
    Une ouvrier peut diriger une et une seul équipe à la fois.
    Une équipe ne peut être dirigée que par un et un seul ouvrier à la fois.
    Nom : cycle.png
Affichages : 389
Taille : 21,0 Ko

    L'idéal aurait été d'avoir le même résultat que si j'avais eu une relation 1,n. C'est à dire que j'aurais eu id_ChefEquipe dans l'entité Equipe. Mais impossible de générer une BDD car c'est un cycle.
    Si je génère telquel avec la relation (1,1), j'ai 2 relations "diriger" et "diriger2", pas de clef étrangère dans Equipe et d'autres choses.

    En cherchant, j'ai compris que c'était normal mais je n'ai pas vraiment trouvé de solution. Je pourrais n'avoir qu'une seule classe mais cela me convient pas. Où essayer de reproduire quelque chose venant de ces deux liens :
    https://www.developpez.net/forums/d7...a/#post4336889
    https://www.developpez.net/forums/bl...re-jambe-bois/

    Mais je n'ai pas réussi à refaire le 1er lien car la version d'AMC n'est pas la même. De plus, je ne sais pas si la solution conviendrait ou non.
    Cette exercice passera par la case Hibernate / JPA par la suite.

    Si vous pouviez m'aider à résoudre ce problème.
    Merci

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    bonsoir,

    Une personne ne peut à un instant "t" ne diriger qu'une seule équipe, mais à "t+1" elle peut en diriger une autre ou plus aucune
    De la même façon, les personnes travaillant dans une équipe peuvent changer dans le temps.

    Ainsi, une façon élégante de résoudre votre problème tout en autorisant la gestion de l'historique des affectations dans les équipes et de la direction des équipes, est d'utiliser le modèle qui suit :

    Nom : MCD.jpg
Affichages : 366
Taille : 60,2 Ko

    La flèche de DI_diriger vers PE_personne est une représentation simplifiée de la contrainte selon laquelle pour une équipe, à une date, une seule personne est dirigeante.
    De la même façon, la flèche vers EQ_equipe est conforme à la contrainte selon laquelle une personne ne peut intégrer qu'une seule équipe à un instant "t"

    J'ai préféré nommer le type d'entité "personne" plutôt que "ouvrier", car ces règles pourraient aussi bien être appliquées à l'ensemble du personnel (cadres, agents de maîtrise, etc.)

    Ici j'ai utilisé Looping pour réaliser le MCD. Looping gère très bien les contraintes d'intégrité fonctionnelles.
    Il y a longtemps que je n'ai plus utilisé power AMC, mais de mémoire il ne gère pas les CIF, il faut donc intervenir dans le MLD en évacuant de la PK les colonnes qui ne doivent plus en faire partie.

    Voici le script généré par Looping pour ce MCD, ici à la sauce SQL server :

    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
    CREATE TABLE PE_personne(
       PE_ident INT IDENTITY,
       PE_matricule CHAR(8) NOT NULL,
       PE_nom VARCHAR(50) NOT NULL,
       PE_prenom VARCHAR(50) NOT NULL,
       PE_ddn DATE NOT NULL,
       PRIMARY KEY(PE_ident),
       UNIQUE(PE_matricule)
    );
     
    CREATE TABLE EQ_equipe(
       EQ_ident INT IDENTITY,
       EQ_code CHAR(5) NOT NULL,
       EQ_designation VARCHAR(50) NOT NULL,
       PRIMARY KEY(EQ_ident),
       UNIQUE(EQ_code)
    );
     
    CREATE TABLE IN_integrer(
       PE_ident INT,
       CA_date DATE,
       EQ_ident INT NOT NULL,
       PRIMARY KEY(PE_ident, CA_date),
       FOREIGN KEY(PE_ident) REFERENCES PE_personne(PE_ident),
       FOREIGN KEY(CA_date) REFERENCES CA_calendrier(CA_date),
       FOREIGN KEY(EQ_ident) REFERENCES EQ_equipe(EQ_ident)
    );
     
    CREATE TABLE DI_diriger(
       EQ_ident INT,
       CA_date DATE,
       Di_dtfin DATE NOT NULL,
       PE_ident INT NOT NULL,
       PRIMARY KEY(EQ_ident, CA_date),
       FOREIGN KEY(EQ_ident) REFERENCES EQ_equipe(EQ_ident),
       FOREIGN KEY(CA_date) REFERENCES CA_calendrier(CA_date),
       FOREIGN KEY(PE_ident) REFERENCES PE_personne(PE_ident)
    );

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut
    Bonjour, l'idée me semble très bonne. Je vais essayé d'implémenter quelque chose avec ça. Je mettrais à jours mon poste.
    Bonne journée

    EDIT: Par exemple, si je dois récupérer la liste du personnel se trouvant dans l'équipe 1.
    INTEGRER

    personne date equipe
    1 02/02/21 1
    1 02/02/21 2
    1 01/01/11 1
    2 01/01/11 1

    Je veux toutes les personnes de l'entité personne ou l'id_equipe est égal à 1.

    A partir de là, j'aurais la ligne 1, 3 et 4. Mais si la date de la ligne 2 est plus proche que celle de la ligne 4 par exemple, je fais une erreur.
    Il me faudrait pour chacun des membres, avoir LA date la plus proche d'aujourd'hui. Puis de sélectionner les membres qui sont dans l'équipe 1.
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * 
    FROM (
      SELECT i.ID_PERSONNE
      FROM Integrer i
      GROUP BY i.ID_PERSONNE
      HAVING MAX(i.DATE_CALENDRIER)
    ) as a, Integrer i2
    WHERE i2.ID_EQUIPE = 1 AND i2.ID_PERSONNE = a.ID_PERSONNE



    Mais cela ne marche pas (je suis plutôt limité par mes aptitudes). Peut être dois-je reformuler une réponse ici par exemple (https://stackoverflow.com/questions/...y-with-maxdate) et ajouté WHERE id_equipe = 1 ?

    Autre chose, un dateTime serait il mieux qu'un date ? et une "dateFin" dans "intégrer" me permettrait il de (me) faciliter mes requêtes SQL ? une dateFin à null voudrait dire que la personne est encore dans l'équipe.

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    Attention, pour savoir si une personne est dans telle ou telle équipe à tel moment, il ne faut pas chercher la date la plus proche, mais le rattachement dont la date de début est inférieur ou égal à la date considérée et dont la date de fin est supérieure à la date considérée.
    Il faut ajouter une date de fin de rattachement comme attribut de l'association IN_integrer (comme je l'ai fait pour l'association DI_diriger)

    Par exemple, pour rechercher les personnes intégrées dans l'équipe n°3 le 10 janvier 2019, on utilisera cette requête :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select PE.PE_matricule
         , PE.PE_nom
         , PE.PE_prenom
    from       PE_personne as PE
    inner join IN_integrer as IN
       on IN.PE_ident=PE.PE_ident
    inner join EQ_equipe   as EQ
       on EQ.EQ_ident=IN.EQ_ident
    where EQ.EQ_ident=3             
      and IN.CA_date > '2019-01-09' 
      and IN.IN_dtfin >'2019-01-10'

    Citation Envoyé par tomateSalade Voir le message
    Peut être dois-je reformuler une réponse ici par exemple (https://stackoverflow.com/questions/...y-with-maxdate) et ajouté "WHERE id_equipe = 1" ?
    Pourquoi aller chercher sur un forum anglophone ce qu'on peut trouver ici

    Citation Envoyé par tomateSalade Voir le message
    Autre chose, un dateTime serait il mieux qu'un date ? et une "dateFin" dans "intégrer" me permettrait il de (me) faciliter mes requêtes SQL ? une dateFin à null voudrait dire que la personne est encore dans l'équipe.
    Le plus souvent, le changement d'équipe se fait pour toute la journée et du coup une date suffit. S'il y a un besoin de changement en cours de journée, alors oui.
    Le plus souvent également, pour la date de fin, on utilise une colonne NOT NULL WITH DEFAULT dont la valeur par défaut est '9999-12-31', plus pratique à manipuler dans les comparaisons de date qu'une colonne marquée "null".

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut
    Bonjour, l'idée est bonne ! Donc à partir de cette requête, j'aurais la liste du personnel dans une équipe X sur une période entre Y et Z.
    Et si je souhaite avoir la liste du personnel travaillant dans l'équipe X, je n'ai qu'à enlever and IN.CA_date > '2019-01-09', c'est bien cela ?

    Dans la bdd que j'ai générée et en utilisant une date NOW() :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT o.ID, o.NOM
    FROM Ouvrier as o
    INNER JOIN Integrer AS i ON i.ID_OUVRIER = o.ID
    INNER JOIN Equipe AS e ON e.ID = i.ID_EQUIPE
    WHERE e.ID = 16          
      AND i.dateFin > NOW()

    Sans l'utilisation d'une dateFin, pour avoir la liste du personnel travaillant dans x équipe, on m'avait conseillé cette requête qui remplie aussi son rôle :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT ID_OUVRIER, ID_EQUIPE, MAX(DATE_CALENDRIER)
    FROM Integrer i
    WHERE ID_EQUIPE = 15   GROUP BY ID_OUVRIER, ID_EQUIPE
    HAVING MAX(DATE_CALENDRIER) = (SELECT MAX(DATE_CALENDRIER) FROM INTEGRER i2 WHERE i.ID_OUVRIER=i2.ID_OUVRIER GROUP BY id_ouvrier)

    Par rapport à la date du calendrier, celle qui est associée avec la clef primaire d'une personne ou d'une équipe, cette dernière sera générée automatiquement ?

  6. #6
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par tomateSalade Voir le message
    Et si je souhaite avoir la liste du personnel travaillant dans l'équipe X, je n'ai qu'à enlever and IN.CA_date > '2019-01-09', c'est bien cela ?
    Attention, pas forcément.
    Prenons un exemple : si je décide d'enregistrer à l'avance le recrutement de monsieur Dupond (il a signé son contrat), qui sera affecté à l'équipe 3 en mars prochain, une requête qui ne tient pas compte de la date de début me dira que monsieur Dupond fait déjà partie de l'équipe 3, alors qu'il n'est pas encore dans l'effectif de l'entreprise !
    C'est pourquoi il est plus prudent d'utiliser une restriction (WHERE) sur la date de début et la date de fin.


    Citation Envoyé par tomateSalade Voir le message
    Dans la bdd que j'ai générée et en utilisant une date NOW() :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT o.ID, o.NOM
    FROM Ouvrier as o
    INNER JOIN Integrer AS i ON i.ID_OUVRIER = o.ID
    INNER JOIN Equipe AS e ON e.ID = i.ID_EQUIPE
    WHERE e.ID = 16          
      AND i.dateFin > NOW()
    Vous avez conservé le nom "OUVRIER", votre besoin ne concerne donc que des populations d'ouvriers ?
    Il est plus prudent d'utiliser un nom moins spécialisé comme "Personne" comme je le proposais plus haut, pour permettre une utilisation quelle que soit la catégorie de personnel.
    Egalement, pour les colonnes foreign key, vous utilisez des noms différents du nom de la même colonne dans la table où elle est primary key (exemple : i.ID_OUVRIER = o.ID)
    D'expérience, cette pratique n'a aucun intérêt. Ca complique la compréhension des requêtes et les études d'impact.
    D'ailleurs, ce n'est pas pour rien que les logiciels de modélisation propagent par défaut le même nom de colonne dans les tables où la colonne est FK.
    D'autant plus qu'une colonne qui s'appelle ID ... c'est un peu court pour savoir de quel identifiant il s'agit.


    Citation Envoyé par tomateSalade Voir le message
    Sans l'utilisation d'une dateFin, pour avoir la liste du personnel travaillant dans x équipe, on m'avait conseillé cette requête qui remplie aussi son rôle :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT ID_OUVRIER, ID_EQUIPE, MAX(DATE_CALENDRIER)
    FROM Integrer i
    WHERE ID_EQUIPE = 15   GROUP BY ID_OUVRIER, ID_EQUIPE
    HAVING MAX(DATE_CALENDRIER) = (SELECT MAX(DATE_CALENDRIER) FROM INTEGRER i2 WHERE i.ID_OUVRIER=i2.ID_OUVRIER GROUP BY id_ouvrier)
    Même remarque que plus haut : si les affectations peuvent être saisies par anticipation, alors cette requête ne fonctionnera pas.


    Citation Envoyé par tomateSalade Voir le message
    Par rapport à la date du calendrier, celle qui est associée avec la clef primaire d'une personne ou d'une équipe, cette dernière sera générée automatiquement ?
    Je ne suis pas sûr de bien comprendre la question.
    CA_calendrier est ce qu'on appelle une entité-type fictive : elle ne deviendra pas une table, elle n'est modélisée dans le MCD que pour contribuer à la constitution des PK des tables issues des associations IN_integrer et DI_diriger.
    Par contre, cette date (CA_date dans mon exemple), ne contribue ni à la clef primaire de PE_personne ni à celle de EQ_equipe

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Avril 2019
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Avril 2019
    Messages : 26
    Points : 27
    Points
    27
    Par défaut
    Je comprends maintenant mieux l'utilité de cette date, une personne n'étant pas forcement encore affectée.
    Mais c'est une notion qui ne sera pas prise en compte, donc je ne m'en inquiète pas trop. La qualité du projet a déjà été amélioréé par rapport à ce qui était demandé.
    Le projet sur lequel je travail n'a pas pour vocation d'étre réaliste et n'a donc pas vraiment de règles "pernicieuses" comme celle-là.
    Et quand j'utilise ce terme, ce n'est pas péjorativement bien évidement. Je dis juste qu'il faut s'adapter aux contraintes existantes sans s'en donner d'autres inutilement.

    Pour la population, elle est uniquement constituée d'ouvriers qui se diviseront en sous catégories par héritage (une sous catégorie étant un "robot" ouvrier, je me vois mal nommer la table personne ...).

    Merci de m'avoir précisé le cas de la table fictive (je ne connaissais pas).
    J'avais remarqué qu'elle n'était pas formatée en sql dans votre précédent poste.
    Je trouvais cela étrange d'avoir une table qui n'aurait eu que des dates et pouvant être identiques ...
    Du coup, je vais la garder sur les schémas mais corriger à la main (je présume ?) la génération de SQL pour ressembler à votre code.

    Merci de votre bienveillance. Je ne marque pas encore le poste comme "résolu". J'attends encore un peu.
    Bonne soirée

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 088
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 088
    Points : 38 393
    Points
    38 393
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par tomateSalade Voir le message
    Je dis juste qu'il faut s'adapter aux contraintes existantes sans s'en donner d'autres inutilement.
    C'est exact : il ne faut ni simplifier sans raison ni ajouter de la complexité là où ce n'est pas nécessaire


    Citation Envoyé par tomateSalade Voir le message
    Merci de m'avoir précisé le cas de la table fictive (je ne connaissais pas).
    J'avais remarqué qu'elle n'était pas formatée en sql dans votre précédent poste.
    En réalité, j'ai triché, car j'avais oublié de cocher la case "entité-type fictive" de Looping qui du coup a généré la table
    Je l'ai donc supprimée du script.
    Si j'avais coché cette case "entité-type fictive", Looping aurait mis le nom de cette entité-type entre parenthèses dans le MCD


    Citation Envoyé par tomateSalade Voir le message
    Je trouvais cela étrange d'avoir une table qui n'aurait eu que des dates et pouvant être identiques ...
    Heu non... dans cette entité-type, la date étant l'identifiant, elle est par définition unique : si on générait la table, il y aurait donc autant de lignes que de dates distinctes
    Par contre, dans les tables issues des association IN_integrer et DI_diriger, il peut y avoir plusieurs fois la même valeur de date, puisque la clef primaire des deux tables issues de ces associations sera composée de plusieurs colonnes dont cette date


    Citation Envoyé par tomateSalade Voir le message
    Merci de votre bienveillance. Je ne marque pas encore le poste comme "résolu". J'attends encore un peu.
    Bonne soirée
    De rien, à bientôt sur le forum

Discussions similaires

  1. [MCD / NF] Relations entre MCD et NF ?
    Par Ekinoks dans le forum Schéma
    Réponses: 2
    Dernier message: 06/12/2007, 14h02
  2. Transformation MCD- MLD relation binaire
    Par lylia SI dans le forum Schéma
    Réponses: 1
    Dernier message: 04/05/2007, 20h37
  3. Réponses: 13
    Dernier message: 15/01/2007, 03h30
  4. MCD - une relation entre 3 entités
    Par fanette dans le forum Schéma
    Réponses: 6
    Dernier message: 23/11/2006, 21h17
  5. [DEBUTANT][MCD] Quelle relation entre 2 entités ?
    Par Ice-tea dans le forum Schéma
    Réponses: 1
    Dernier message: 18/10/2006, 23h03

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