Relation Plusieurs à Plusieurs (n:n)

Comment définir une relation Plusieurs à Plusieurs dans Access ?

Solution

Il est impossible de lier directement 2 tables par une relation de Plusieurs à Plusieurs. Il faut systématiquement passer par une troisième table.

On suppose que vous avez déjà 2 tables construites correctement (notamment avec une clef primaire chacune). Dans ce cas :

  1. Créez une troisième table, qu’on appellera « table de jonction« .
  2. Dans cette table, reprenez la clef primaire des tables 1 et 2.
  3. La clef primaire de la table 3 sera au minimum la combinaison des 2 autres clefs.
  4. Dans la fenêtre Relations, tracez maintenant une relation classique « 1 à Plusieurs » entre les tables 1 et 3, et faites de même entre les tables 2 et 3. 

Exemple

Dans l’exemple suivant…

  • un réalisateur peut tourner plusieurs films
  • un film peut être tourné par plusieurs réalisateurs.
    C’est plus rare, mais ça se fait ! Matrix est tourné par les frères Wachowski, par exemple…

Donc on se retrouve bien avec une relation « Plusieurs à Plusieurs ».

  1. Créez donc la table intermédiaire (vous lui donnez un nom quelconque, meilleur que le mien :-))
  2. Ajoutez à cette table un champ Numéro Film qui permettra la liaison avec [tbl Films].[Numéro Film].
    Pris individuellement, ce champ n’est pas clef primaire (on pourrait le penser en voyant le symbole de clef) : il s’agit juste ici d’un champ Numérique/Entier long, indexé avec doublons. En d’autres termes, il s’agit d’une clef étrangère.
  3. Créez un champ Numéro Réalisateur qui permettra la liaison avec [tbl Réalisateurs].[Numéro Réalisateur].
    Comme précédemment, ce champ n’est pas clef primaire individuellement : il s’agit juste ici d’un champ Numérique/Entier long, indexé avec doublons.
  4. Par contre, la clef primaire de la table de jonction est composée des 2 champs Numéro Film et Numéro Réalisateur (d’où la double clef).

Notes
  • Dans l’exemple plus haut, la table de jonction ne contient que 2 champs (les clefs étrangères). Mais elle peut contenir d’autres informations, si nécessaire.
  • Dans certains cas, il ne suffit pas de joindre les 2 clefs étrangères (dans la table de jonction) pour en faire une clef primaire. Parce que la saisie serait trop restrictive. Dans ce cas, la table de jonction comporte généralement d’autres champs, et vous pouvez en inclure un 3ème, voire un 4ème dans la clef primaire. Rappelez-vous qu’il a été dit plus haut que « la clef primaire de la table 3 est au minimum la combinaison des 2 autres clefs ». Au minimum.
  • Si on poursuit ce raisonnement, vous risquez parfois d’avoir une clef primaire composée de plein de champs, ce qui peut être lourd à gérer. Vous pouvez alors la remplacer par une clef primaire mono-champ (le champ étant de type NuméroAuto). Mais il serait bon que la combinaison des autres champs reste indexée sans doublons.

Vous aimerez aussi...

19 réponses

  1. Hervé Inisan dit :

    Didi > Tu fais la saisie directement dans les tables ? Dans ce cas, il faut que tu saisisses :

    1. L’article (dans sa table).
    2. L’auteur (dans sa table).
    3. Une ligne dans la table de jonction, qui reprend la clef primaire de l’article et celle de l’auteur (puisque la table de jonction contient les clefs primaires des 2 autres tables).

    Avec un formulaire et un sous-formulaire, on peut faire en sorte que cette saisie soit plus simple.

  2. Didi dit :

    Bonjour,
    Mon problème est tout simple et pourtant je n’arrive pas à en trouver la solution. J’ai fait trois tables (auteurs, articles et la jonction) pour arriver aux relations n-à-n. Mais comment puis-je faire pour entrer les données dans mes tables?? Ça me tue! Dès que je veux entrer des données dans ‘Auteurs’ par exemple, et les mettre en relations avec ‘article’, Access 2003 me dit que je ne peux pas ajouter ou modifier un enregistrement car l’enregistrement associé est requis dans la table ‘article’. Comment puis-je entrer les données reliées à partir de mes tables en relations?

  3. Hervé Inisan dit :

    Aude > Merci aussi ! 🙂

  4. aude dit :

    Un grand merci à Hervé Inisan pour ses précisions sur la table de liaison. Si cela peut aider d’autres débutants comme moi, comme le concept de cette relation particulière me laissait un peu perplexe, j’ai fait un formulaire d’essai sur ma table générale (« Photographies ») après avoir créer la table de liaison EtatsPhotographies et introduits quelques enregistrements fictifs pour tester le bazar. Voir le résultat sur le formulaire a énormément clarifier les choses !!!! (et permis de voir que je ne m’étais pas plantée cette fois). Encore un grand merci.

  5. Hervé Inisan dit :

    Aude > Peut-être que cette autre page du site peut aider à modéliser les relations (il y a des vidéos explicatives).

    Ensuite, d’un point de vue technique, il ne s’agit pas de « créer 2 clefs », mais de créer « 1 clef composée de 2 champs » (la nuance est fine, mais c’est important en terme de logique). Du coup, il faut :

    1. Sélectionner les 2 champs, en mode Création de table.
    2. Cliquer sur l’icône Clé primaire.
      2 symboles de clefs apparaîtront pour visualiser les champs impliqués, mais la table n’a bien qu’une seule clef primaire.
  6. Djeli dit :

    Bonjour,
    j’ai résolue mon problème d’une autre manière que j’ai exposé sur le forum sous le titre « Affectation automatique ».
    Merci

  7. Aude dit :

    Bonjour,

    je suis en train de modéliser une bd pour créer un inventaire de photographies anciennes interrogeable facilement. Bref, j’ai besoin de créer une table de jonction, mais malgré les explications données (merci d’ailleurs), je n’y parviens pas. En résumé, la table principale (T_photographies) comprend un champ « Etat du tirage » (Etat) qui doit être relié à une table T_Etats. Comme les photos anciennes présentent souvent plus d’un état (jaunissement + rayures par ex)et qu’un état va forcément concerner plusieurs photos, j’ai donc besoin d’une table de jonction. Mais, diantre !, Access refuse de faire deux clés ! Ou bien j’ai mal compris l’explication ? Serait-il possible de développer la méthode plus en détail pour une pauvre débutante ? Un grand merci pour vos conseils en tout cas !

  8. Hervé Inisan dit :

    Djeli > Difficile de répondre en détail sans la structure des tables (et les relations).

    Par contre, sur le principe, l’idée est, au moment de la validation d’un élève :

    1. De vérifier s’il est déjà affecté à une classe. Si oui, on ne fait rien de particulier.
    2. Si ce n’est le cas, on vérifie le niveau (6, 5, 4…).
    3. On parcourt les classes liées au niveau en calculant le nombre d’élèves.
    4. Si le quota de la classe n’est pas atteint, on affecte l’élève à la classe.
  9. Djeli dit :

    Bonjour,

    Dans mon application j’ai une table élèves dont dépend le frmElèves avec un champ Niveau (pour une 1ère inscription d’un nouveau élève)et un sous formulaire sfrmRéinscription avec un champ niveau(pour les réinscriptions afin de créer un rapport de suivi des cursus scolaires).

    j’ai un frmClasse ou je crée les niveaux (6ème, 5ème, 4ème…) et son sfrmClasse ou je crée les classe (6ème n°1, 6ème n°2….)et fixe l’effectif maximum par classe.

    Dans les deux cas (1ère inscription et réinscription), ce que je souhaite fait faire a mon application est lorsque j’inscris un élève dans un niveau (6ème, 5ème, 4ème…), l’application affecte automatiquement l’élève a une classe (6ème n°1, 6ème n°2…., 5ème n°1, 5ème n°2….)en fonction de l’effectif maximum par classe du sfrmClasse.

    Merci d’avance

  10. Hervé Inisan dit :

    Djeli > Tout dépend du format dans lequel est fournie la liste des classes, et de la structure des tables Access. Je n’ai pas assez d’infos pour en dire plus sur la façon d’y arriver… 😉

  11. Djeli dit :

    Bjr
    je suis entrain de développer une application pour géré un établissement scolaire. jusqu’ici tout va bien mon application fonction parfaitement de l’inscription jusqu’au bulletin trimestriel.
    Mon souhait est de créer dynamiquement les classes scolaires à partir des inscriptions des élèves, ce que je fait manuellement dans mon application.
    Merci d’avance.

  12. Hervé Inisan dit :

    Naeva > Content que ça puisse dépanner ! 🙂

  13. Naeva dit :

    Bonjour Hervé,
    Merci pour les liens qui traitent de la modélisation, ils ont permis de mettre de l’ordre dans mes idées, ce qui est déjà un fort bon début. J’étais tellement concentrée sur le besoin de faire un lien entre les tuteurs et les élèves que j’en oubliais leur plus grand point commun, merci de m’avoir ramenée sur terre.

    J’ai ajouté les tables matières, centre d’aide, session et résultats. La table jumelage me servira à relier le tout. Je peine encore à établir correctement les relations pour que tout fonctionne rondement, mais je crois bien percevoir la lumière au bout du tunnel.

    Merci de ton aide.
    Bonne journée.

  14. Hervé Inisan dit :

    Naeva > Effectivement, l’analyse est le point le plus important de la base de données… avant la construction de la base. Peut-être que cette série d’articles (et les vidéos incluses) peuvent déjà donner des pistes. Ils indiquent comment modéliser les tables et les différents types de relations.

    Une remarque importante : dans ton cas, il ne faut pas voir les tuteurs et les étudiants comme des entités (des tables) différentes. 2 raisons à cela :

    1. Les champs qui les décrivent sont identiques.
    2. Et surtout : chacun peut jouer le rôle de l’autre.

    Un tuteur est donc un étudiant, et vice-versa. Donc on peut considérer que ce sont des « individus », des « participants », peu importe comment on les nomme. 🙂

    A vue de nez, il manquerait aussi quelques tables :

    • Une table Matières, pour normaliser la saisie.
    • Une table qui va faire la jonction entre les tuteurs/étudiants, les matières et peut-être les centres d’aides. C’est sans doute cette table qui joue le rôle central du modèle : l’affectation des tuteurs aux étudiants et aux matières.

    A affiner bien sûr (les articles plus haut devraient aider).

    Ouala !

  15. Naeva dit :

    Bonjour,
    Je débute avec Access et je suis chargée de mettre en place une base de données pour gérer les utilisateurs des services de tutorat de l’établissement d’enseignement où je travaille. J’aurais besoin de quelques conseils pour bien structurer le tout.

    Il faut savoir qu’un étudiant peut avoir des tuteurs dans différentes matières.
    Un tuteur peut aider plusieurs étudiants dans la même matière, mais il peut aussi aider dans plusieurs matières.
    Un étudiant peut agir à titre de tuteur (et vice versa).
    Tuteurs et élèves peuvent être inscrits pendant plusieurs sessions (ils doivent se réinscrire chaque session)
    Les tuteurs et les élèves peuvent être rattachés à plusieurs centres d’aide.
    Un centre d’aide peut aider dans plusieurs matières ex. Scientraide : chimie et physique

    Vous voyez le casse-tête?

    Étudiant:
    No_etudiant
    Date_inscription
    No_DA
    Nom
    Prénom
    Courriel
    Téléphone
    Programme
    Centre_aide
    Matière
    Tuteur

    Tuteur:
    No_tuteur
    Date_inscription
    No_DA
    Nom
    Prénom
    Courriel
    Téléphone
    Programme
    Centre_aide
    Matière
    Étudiant

    Centre d’aide:
    Centre
    Matière

    C’est la façon d’organiser les liens entre les tables et la justesse des tables qui me font hésiter. J’apprécierais beaucoup profiter d’un avis expérimenté pour structurer correctement cet outil destiné à servir pendant de nombreuses années. Merci beaucoup.

  16. Hervé Inisan dit :

    eos > Difficile de répondre en SQL sans connaître les noms des tables et des champs. Mais par contre, graphiquement, il faut faire la chose suivante : créer une requête, et y sélectionner les 4 tables concernées (Patients, Maladies, Maladies+Symptômes et Symptômes) plus Contamination (?). Si tes relations sont bien construites, ces 4 tables apparaissent comme liées dans la requête. Ensuite, tu peux placer les champs sur la grille, et les critères qui t’intéressent (sur id_patient notamment).

    Dans ta requête SQL, il manque certaines tables, ainsi que les jointures (INNER JOIN) qui les relient.

    Ensuite, si la requête produit les bonnes infos, tu peux ajouter un regroupement (GROUP BY) sur les champs appropriés ou une clause DISTINCT. L’une ou l’autre de ces techniques permettront de garder les valeurs différentes.

  17. eos dit :

    Bonjour,
    Alors voici mon soucis, j’ai 2 tables : maladies et symptomes et j’ai donc crée une table intermédiaire qui réuni les colonnes « nom de la maladie » et le « symptome ».
    Sachant, qu’une maladie peut avoir plusieurs symptome et un symptome plusieurs maladie.
    si je fait:

    select nom_maladie from maladie_symptomatique where id_sympt in (select id_sympt from contamination where id_patient=1);

    pour qu’il me renvoie les symtpome du patient 1 selon la maladie qu’il a, cette requete me renvoie en fait toutes les maladie correspondant aux symptome…….

    comment fai pour avoir unique les symptomes de la maladie du malade??

    ex: ce que renvoie le « select ci- dessus »
    nom_maladie
    ———————–
    acne
    acne
    acne
    acne
    psoriasis
    syndrome premenstruel
    syndrome premenstruel
    syndrome premenstruel
    syndrome premenstruel

    au lieu de ce que je veux:

    nom_maladie
    ———————–
    acne
    acne
    acne
    acne

    au pire ou au mieux:
    nom_maladie
    ———————–
    acne

    merci d’avance!!!

  18. Hervé Inisan dit :

    wagolo > Voir ma réponse à Yeo sur cette autre page du blog, ainsi que cette conversation du forum. Vous avez visiblement le même exercice à faire ? 😉

  19. wagolo dit :

    SALUT A tous,

    Je suis nouvelle sur le Forum et J’aimerais partager mon Projet avec tout le monde afin de pouvoir beneficier de l’appui Technique de tous. En effet, Je Calcul les Moyennes Scolaires de nos eleves avec access depuis plus de 5 ans, mais avec les besoins qui ne sessent d’augmentés Excel semble Etre ne plus adapté, donc nous voudrions bien créer une application avec Access qui nous permettra d’ëtre encore plus dynamique dans la suivi du coursus Scolaire des élèves de l’etablissement. Le suivi de chaque Elève se fait chaque année scolaire. la 1ère année, il fait une inscription et les autres années il fait une réinscription soit en classe supérieur ou dans la même classe selon son travail sur toute l’année. Les moyennes se calculent avec les coéficients de chaque matière respectif et après le calcul des moyennes coéficientées la moyennes trimestrielles est calculée et un rapport de fin de trimestre est etablit. l’année scolaire compte 3 trimestres, chaque trimestre a son coéficient. Pendant l’année scolaire un ou plusieurs élèves peuvent être dispensé en Sport.

    Voici les tables créer pour le moments et avec les relation

    entre les tables CLASSE et ELEVE, grâce au champ commun Code_classe
    entre les tables ELEVE et NOTATION, grâce au champ commun Num_élève
    entre les tables EVALUATION et NOTATION, grâce au champ commun Num_évaluation
    entre les tables CLASSE et EVALUATION, grâce au champ commun Code_classe
    T_Elève: N°Matricule, Nom, Prenom…..

    T_Classe: N°Classe, 6è,5è,4è…..Serie, Cycle, Description

    T_Evaluation: N°Eval, Date Eval, type,

    T_Notation: N°Eval, Type, coef

    Je vous donne le temps et vous demande votre soutient car c’est nécessaire.

    PS: j’ai plusieurs fois lu le blog sur la normalisation et les rélations entre les tables , ce qui ma d’ailleurs permis de comment ce travail.

    Merci a tous

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *