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

MySQL Discussion :

Modélisation relation many to many


Sujet :

MySQL

  1. #1
    Modérateur

    Modélisation relation many to many
    Bonjour,

    Quand on a trois tables comme ceci :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    USER (id, ...)
    BADGE (id, ...)
    USER_BADGE (#user_id, #badge_id)


    Où un user peut avoir plusieurs badges et la table USER_BADGE a comme clé primaire composite user_id et badge_id, il parait logique, en théorie comme en pratique, de laisser tel quel.

    Si on rajoute une colonne dans la table USER_BADGE, ce qui donnerait :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    USER_BADGE (#user_id, #badge_id, gain_date)


    Est-il correct de laisser la table avec sa clé primaire composite ? Ou faut-il rajouter un id unique auto-incrémenté et faire un INDEX UNIQUE sur user_id et badge_id ? En théorie ? En pratique ?

    J'ai déjà plus ou moins ma réponse en pratique, puisque Doctrine considère qu'à partir du moment où une relation many to many a des colonnes supplémentaires, il faut la transformer en relation one to many et many to one.
    Ma question porte plus sur l'aspect théorique de la chose et sur l'aspect pratique hors Doctrine.


  2. #2
    Expert éminent sénior
    Salut Bisûnûrs.

    Citation Envoyé par Bisûnûrs
    Où un user peut avoir plusieurs badges ...
    Est-ce qu'un badge peut appartenir à plusieurs utilisateurs ? Je suppose que non.
    De ce fait, il ne sert à rien de créer une table association "user_badge".

    Ajoutez dans la table "badge", une clef étrangère qui va pointer sur la table "user".
    Ainsi plusieurs badges peuvent appartenir à la même personne.
    Si un badge n'appartient à personne, mettez NULL dans la clef étrangère.

    Quelle est la signification de votre colonne "gain_date" ?
    A première vue, cette colonne est une date et est liée à un badge.
    Elle a pour vocation d'indiquer quand vous avez fait usage de ce badge (horodatage).
    Vous ne pouvez pas la mettre dans la table badge car sa valeur n'est pas unique.
    Ben oui, si vous faites plusieurs fois par jour l'usage de ce badge, on aimerait connaitre toutes vos interventions.

    Il faut placer cette colonne dans une table qui sera liée au badge, qui lui-même est lié à un user.
    La structure de la table "horodatage" est : (id, #badge_id, gain_date).

    Citation Envoyé par Bisûnûrs
    Est-il correct de laisser la table avec sa clé primaire composite ?
    L'erreur dans votre organisation est de considérer qu'un badge peut appartenir à plusieurs personnes.
    Même si vous ne gérez pas ce cas, on peut créer une ligne où un badge est partageable entre deux utilisateurs.

    Sur votre table association, vous introduisez une colonne date+heure servant à faire la distinction dans l'usage du badge.
    De ce fait, la clef primaire doit être complétée par cette nouvelle colone afin de rendre unique la ligne.

    Citation Envoyé par Bisûnûrs
    Ou faut-il rajouter un id unique auto-incrémenté et faire un INDEX UNIQUE sur user_id et badge_id ?
    A priori, il n'est pas nécessaire d'introduire une colonne auto_incrémenté.

    Normalement, pour accéder à cette table, vous devez avoir la connaissance du user et de son badge.
    Ces clef étrangères sont en fait des clefs techniques pointant sur les tables parents.

    Citation Envoyé par Bisûnûrs
    En théorie ? En pratique ?
    Pour la théorie, je viens de répondre.
    Dans la pratique, connaissant l'identifiant on détermine le user, voire même son dernier usage.

    Je ne suis pas un spécialiste de ce qui concerne la modélisation.
    Comme un badge appartient à un et un seul utilisateur, connaissant son identifiant, on peut retouver son utilisateur et l'heure de son dernier usage.

    Si maintenant, vous devez ajouter d'autres informations comme le lieu, cela se fait sur la clef primaire badge_id + gain_date.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Expert éminent sénior
    Bonjour,

    Si toutefois un badge peut bien correspondre à plusieurs utilisateurs (vu le titre du sujet "many to many" c'est probablement le cas) alors qu'il y ait ou non des attributs supplémentaires dans la table USER_BADGE ne justifie en rien de modifier l'identifiant primaire de cette table.

    Et comme vous aurez de toute façon besoin des FK user_id et badge_id dans cette table, autant qu'ils soient également utilisés comme PK plutôt que de créer un identifiant supplémentaire qui n'apportera rien.

    Citation Envoyé par Bisûnûrs Voir le message
    J'ai déjà plus ou moins ma réponse en pratique, puisque Doctrine considère qu'à partir du moment où une relation many to many a des colonnes supplémentaires, il faut la transformer en relation one to many et many to one.
    Il n'en est rien, une table associative porteuse d'attributs fonctionnels peut tout à fait être légitime.

    Exemple issu d'une discussion récente : si un entrepôt concerne plusieurs articles et qu'un même article peut être dans plusieurs entrepôts alors on a le modèle de données suivant
    EN_entrepot (EN_ident, EN_code, EN_surface, EN_volume...)
    AR_article(AR_ident, AR_reference, AR_designation, AR_prix_unit...)
    LO_localisation(AR_ident#, EN_ident#, LO_quantite...) <== l'attribut quantité a toute sa place dans la table associative "localisation"

  4. #4
    Expert éminent sénior
    Salut à tous.

    Avant de poursuivre, j'aimerai savoir ce que vous entendez par le partage du badge par plusieurs personnes ?
    On peut comprendre mon interrogation de deux façons :

    1) son attribution se fait à une et une seule personnes durant une période limitée dans le temps.
    Par exemple, par accéder à une salle en libre service. Ce qui nécessite au préalable de faire une réservation.
    Connaissant la date de son utilisation, on peut remonter à l'utilisateur, puisque celui-ci sera unique.

    Bien sûr, on peut attribuer le badge à une autre personne, après que la personne précédente n'en ai plus l'usage.

    2) le badge est partagé entre plusieurs personnes, sans que l'on sache qui est le porteur à un instant donnée.
    Ce cas me semble bizarre car je n'ai pas en entreprise rencontré ce cas.

    Dans le cas 1) la table d'association n'est pas nécessaire alors que dans le cas 2), elle l'est.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Modérateur

    Hello,

    Merci à vous deux pour vos réponses.

    @Artemus24 : Il y a confusion sur la signification d'un badge. Je ne parle pas ici d'un badge nominatif pour accéder ou non à une zone par exemple. Il s'agit plus d'un système de jeu, où chaque utilisateur peut gagner un ou plusieurs badges en fonction des actions qu'il fait. Un badge peut donc être gagné par plusieurs personnes.

    La colonne "gain_date" serait donc la date d'obtention de ce badge. L'exemple est peut-être mal choisi, je ne pensais pas que ça pouvait être détourné de cette manière, c'est pour ça que j'avais précisé many to many.

    @escartefigue : Merci beaucoup, tu confirmes exactement ce que je pensais. En théorie donc, une table associative peut très bien avoir des colonnes supplémentaire. En pratique, normalement, également.

    Le problème vient donc de Doctrine.

  6. #6
    Expert éminent sénior
    Ce message n'a pas pu être affiché car il comporte des erreurs.

  7. #7
    Modérateur

    C'est un ORM pour PHP utilisé entre autres par le framework Symfony. Autant dire qu'il est difficile d'y couper quand on veut utiliser Symfony !

###raw>template_hook.ano_emploi###