Leçon 16 : Relations

Temps nécessaire pour suivre cette leçon : Une grosse demie heure

Pour suivre cette leçon, vous devez avoir suivi les leçons précédentes. Ou plus précisément, vous devez être en possession de la base de données ProFormation.mdb telle qu'elle était à la fin de la leçon précédente. Si vous n'êtes pas certain de l'avoir, vous pouvez la télécharger ici

Aperçu de cette leçon

Dans cette leçon, nous allons regarder en détail les relations entre les tables : Vous apprendrez que les relations sont une sorte de "police", un "Service de contrôle" qui vérifie que votre base de données reste bien cohérente au niveau des données qu'elle contient.

Sommaire

  1. Affichage des tables dans les relations
  2. Déplacement/Redimensionnement des tables dans la fenêtre des relations
  3. Création d'une relation simple entre 2 tables
  4. Masquage/apparition des tables dans les relations
  5. Suppression d'une relation entre 2 tables
  6. Tout cham de toute table peut être lié à n'importe quel champ de n'importe quelle autre table
  7. Application de l'intégrité référentielle
  8. Erreur de correspondance entre 2 tables lors de l'application de l'intégrité référentielle
  9. Mise en symbiose des 2 tables qui doivent être mises en relations
  10. Test de la sécurité des données offerte par l'application de l'intégrité référentielle
  11. Comparaison de l'intégrité référentielle avec la propriété de champ "Limité à liste"

Nous avons vuà la leçon 14 comment faire pour empêcher de saisir une valeur qui n'est pas proposée dans une liste déroulante : . Mais attention : Cette option n'entre en jeu qu'à partir du moment ou vous définissez Limiter à liste : Oui. Jusque-là, on pouvait écrire n'importe quoi... Je m'explique :

  1. Dans la liste PaysOrigine, indiquez : "Limiter à liste : Non"
  2. Lancez la table en mode saisie de données
  3. installez manuellement les pays suivants :
    Vous constatez que Bill Clunton et Michael Jordane sont issus de pays qui n'existent PAS dans la liste déroulante (et donc évidemment qui n'existent pas non plus dans T_Pays)
  4. Remettez Limiter à liste : Oui pour le champ Pays :
  5. Relancez T_Client en mode saisie de données, et essayez maintenant de préciser que Josiane Balasco vient de "Frense" : . Vous pouvez, mais dès que vous allez changer de champ ou d'enregistrement, vous aurez le message . C'est ce qu'on voulait mais...

Ca n'empêche pas que Bill Clunton provient encore de YoupiLand (qui est un pays inexistant), et Michael Jordane, qui vient d'U.S.A... Au lieu de USA (Sans les points entre les lettres... C'est important !)

Ce qui fait qu'en définitive, cette sécurité n'est pas suffisante.


Affichage des tables dans les relations

Nous allons donc lier les deux tables ensemble, c'est ça ?

Oui. Quittez la table T_Client, et allez dans Outils/Relations. Cette boîte de dialogue apparait : . Cliquez deux fois sur T_Client, et également 2 fois sur T_Pays : . Cliquez ensuite sur . Vos deux tables T_Client et T_Pays sont maintenant apparentes sur votre écran, comme ceci : .


Déplacement/Redimensionnement des tables dans la fenêtre des relations

Vous pouvez redimensionner ou déplacer les tables pour visualiser la totalité des champs de vos tables : .


Création d'une relation simple entre 2 tables

Une fois que vous avez sous les yeux les 2 tables avec tous leurs champs (surtout la table T_Client qui contient pas mal de champs), nous allons essayer de les lier ensemble : Cliquez sur Pays de T_Pays, et faites le glisser sur IDClient de T_Client : . Vous constatez que quand vous faites glisser la souris, elle se trasforme en petit rectangle ().

Cette boîte de dialogue apparait : . Cliquez sur . Maintenant, les 2 tables sont liées comme ceci : par une petite ligne noire.


Masquage/apparition des tables dans les relations

Peut-on supprimer cette relation ?

Oui. Cliquez sur T_Pays , et appuyez sur la touche DELETE

Et pour la faire réapparaître ?

Cliquez sur l'icône , et cliquez 2 fois sur T_Pays : , puis cliquez sur .

Ah oui mais... la relation est réapparue aussi. En fait, je voulais supprimer la relation, pas la table !

Oui, je vous ai fait faire quelque chose de faux exprès.

En fait, quand on clique sur une table et qu'on la supprime avec la touche de clavier DEL (quand on est dans les relations évidemment), en fait, on ne supprime rien du tout : Ni la table, ni la relation qu'elle possède avec d'autres tables. En réalité, tout ce qu'on fait, c'est MASQUER la table du tableau des relations. La table est toujours là, la relation aussi, mais simplement, on ne les voit plus !


Suppression d'une relation entre 2 tables

Je reviens alors à ma question : Comment faire pour supprimer ma relation entre T_Client et T_Pays ?

Il faut cliquer précisément sur la petite ligne noire qui relie les 2 tables : , et seulement quand la ligne est sélectionnée (elle devient un tout petit peu plus épaisse quand on clique dessus), on appuye sur DEL (). Un message de confirmation apparait : . Cliquez sur , et la relation a maintenant disparu. Vous vous retrouvez avec vos 2 tables, comme au début : .

Impeccable ! Mais je reviens à cette relation : Nous avons lié IDClient et Pays... C'est bizarre... Ce n'est pas plutôt Pays et PaysOrigine qu'il faut lier

Si, bien sûr. Mais j'ai lié exprès deux champs qui n'ont rien à voir l'un avec l'autre simplement pour montrer qu'on peut lier n'importe quel champ de n'importe quelle table avec n'importe quel autre champ de n'importe quelle autre table.


Tout cham de toute table peut être lié à n'importe quel champ de n'importe quelle autre table

Je ne vois pas l'intérêt de pouvoir lier n'importe quoi comme ça...

Il n'y a pas d'intérêt autre que de dire : "Tiens, cette table possède un champ qui est très copain avec un autre champ d'une autre table". Comme par exemple, le champ PaysOrigine de T_Client est très copain avec le champ Pays de la table T_Pays en ce sens que c'est un PaysOrigine de la table T_Client qui est une liste déroulante basée sur Pays de la table T_Pays.

Ah c'est tout ! Bôf...

Oui, c'est tout... POUR L'INSTANT !

Nous allons maintenant réaliser une relation qui "tient la route" : Nous allons enquelque sorte "marier" les deux tables T_Client et T_Pays. Rappelez-vous : Un peu plus haut dans la leçon, nous avions défini des pays pour le moins fantaisistes : Michael Jordane provient des U.S.A (alors que le "vrai" pays se nomme USA - sans les points), et Bill Clunton vient carrément de YoupiLand (Un pays de ma plus pure imagination).

C'est le désordre le plus total ! Il faudrait, pour que notre base de données soit fiable, que tous les clients, SANS EXCEPTION, proviennent d'un pays QUI EXISTE dans la table de référence T_Pays. Si un client vient de "U.S.A" alors U.S.A DOIT exister dans T_pays. Pareil pour YoupiLand (Ce qui est idiot, puisque YoupiLand est un pays fantaisiste : En fait, PERSONNE n'est issu de YoupiLand !).


Application de l'intégrité référentielle

Concrètement ?

On ne dit pas "Marier les tables". Dans le jargon très poétique des informaticiens, nous disons "Appliquer l'intégrité référentielle". Pour ce faire, créez une relation entre Pays de T_Pays jusque PaysOrigine de T_client (Le sens dans lequel vous allez n'a aucune importance : Que vous partiez de T_Client pour aller vers T_Pays ou l'inverse ne change rien). La boite de dialogue suivante apparait : . Cochez "Appliquer l'intégrité référentielle" : . Cliquez sur .


Erreur de correspondance entre 2 tables lors de l'application de l'intégrité référentielle

Oula !!! J'ai un monstrueux message d'erreur !!!

Oui. C'est un des messages d'erreur les plus communs d'Access. De plus, il n'est pas très compréhensible... Je vous le traduit :

Impossible de créer cette relation et surtout, d'appliquer l'intégrité rérérentielle (Marier les 2 tables)

Les données (ce que vous avez écrit) dans la table "T_Client" ne respectent pas les règles d'intégrité référentielle.
Par exemple, certains enregistrements (certains clients) font peut-être (même sûrement) référence à un Pays dans la table associée (T_Pays) sans qu'il y ait d'enregistrement pour ce pays dans la table primaire (Un ou plusieurs pays fantaisistes existent dans la table T_Client sans qu'ils existent dans T_Pays).

Modifiez les données (Partez à la chasse aux pays fantaisistes dans la table T_Client pour les remplacer par des pays normaux - c'est à dire des pays qui existent dans T_Pays) pour tous les enregistrements (Clients) associés.
Si vous souhaitez créer la relation sans suivre les règles d'intégrité référentielle (si finalement vous vous en fichez que les clients fassent partie de pays non référencés dans la table T_Pays), désactivez la case à cocher "Appliquer l'intégrité référentielle (enlever la coche)"

Cliquez sur OK (Pas le choix)

Donc, en clair ?

Tant que vous avez des clients qui font partie d'un pays qui n'existe pas dans la table T_Pays, pas question d'appliquer l'intégrité référentielle... Eh oui... Si vous aviez 500'000 clients, et qu'UN SEUL d'entre eux faisait partie d'un pays non référencé, vous auriez eu le MEME message d'erreur...

Cette relation, c'est un peu la police de votre base de données.

Que fais-je, alors ?


Mise en symbiose des 2 tables qui doivent être mises en relations

Nous allons corriger tout ça ! Marche à suivre :

  1. Fermez les relations
  2. Allez dans T_Client
  3. Précisez que Bill Clunton ne vient PAS de YoupiLand, mais, par exemple de Belgique (ce n'est pas vrai, mais ça n'a aucune importance sur le plan d'Access : Belgique existe dans T_pays, DONC ça marche). Et Michael Jordane vient d'Italie (Admettons) :
  4. Fermez T_Client (Très important de fermer toutes les tables avant d'aller dans les relations, sinon, il n'y a rien qui marche)
  5. Retournez dans les relations
  6. Faites glisser à nouveau Pays de T_Pays sur PaysOrigine de T_Client
  7. Cochez la case "Appliquer l'intégrité référentielle"
  8. Cliquez sur OK

Si vous avez parfaitement suivi les instructions, vous ne devriez PLUS avoir de message d'erreur, mais Access devrait vous avoir créé la relation entre les 2 tables comme ceci : . Vous constatez que la relation possède un petit et un petit . C'est le signe que la relation s'est bien déroulée, et que, surtout, l'intégrité référentielle s'est appliquée correctement. A partir de maintenant, on peut dire que les deux tables sont liées "A la vie, à la mort". Dès cet instant, il va être SRICTEMENT IMPOSSIBLE d'attribuer pour un client quelconque un pays qui n'existe pas dans ta table T_Pays (ce qui est évidemment très rassurant)

Pourtant, nous avons plein de clients qui n'ont pas de pays du tout. C'est normal ?

Oui. Pas de pays, c'est correct. Ce qui n'est pas correct, c'est uniquement le fait d'avoir un pays non référencé. Mais un pays vide, ça ne fait rien. Heureusement... Parce que si vous avez à entrer un nouveau client dont vous ne connaissez pas le pays, il faut bien pouvoir le laisser vide...

Justement, j'ai constaté dans T_pays, que la Suisse ne correspond à aucun client...

Dans ce sens là, pas de problème ! Dans T_Pays, vous pouvez avoir autant de pays que vous voulez qui ne sont pas référencés chez les clients, c'est logique. C'est seulement dans le sens d'un client qui fait partie d'un pays qui n'existe pas dans T_Pays qui pose un problème.

Heureusement qu'on peut ajouter des pays dans T_Pays sans qu'il y ait d'enregistrement correspondant dans les clients ! Imaginez qu'on ne puisse pas dans T_Pays avoir de pays qui ne correspondent à aucun client...

Tout à coup, vous avez un nouveau client, John Lemon qui vient de Grande-Bretagne : Vous ne pourriez pas indiquer qu'il vient de Grande-Bretagne parce que bien sûr, Grande-Bretagne n'existe pas dans T_Pays, mais vous ne pourriez alors pas non plus ajouter Grande-Bretagne dans T_Pays sous prétexte qu'il n'y a encore aucun client de Grande-Bretagne... C'est le serpent qui se mord la queue... Vous suivez toujours ?


Test de la sécurité des données offerte par l'application de l'intégrité référentielle

OK. Donc, maintenant, ce n'est plus possible d'avoir des pays non correspondants ?

Exactement. D'ailleurs, nous allons essayer. Quittez les relations, et ouvrez T_Client. Essayez de définir Autriche pour Juliette Griko, appuyez sur ENTER. Vous avez cette erreur :

Je la connais cette erreur ! Ca n'a rien a voir avec les relations, c'est simplement parce que nous avons défini "Limiter à liste" : Oui !

Bien vu ! Effectivement. MAIS... Maintenant, en mode création, définissez justement pour le champ Pays "Limiter à liste" : NON. Lancez la table en mode saisie de données, et essayez d'entrer à nouveau Autriche pour Juliette Griko. Appuyez sur ENTER

Oui... Effectivement, cette fois, je peux, il n'y a plus d'erreur... Pourtant d'après les relations, c'est bien clair qu'on ne devrait pas pouvoir : Autriche n'existe pas dans T_Pays !

Oui mais vous n'avez pas encore enregistré votre changement... Quand vous avez appuyé sur ENTER, c'est maintenant le champ suivant qui est sélectionné (Ville), mais TOUJOURS de Juliette Griko... C'est suelement quand vous allez enregistrer que ça va mal se passer : Essayez de descendre d'un enregistrement :

"Vous avez essayé d'entrer Autriche, qui n'est pas un pays existant dans T_Pays"

Ca d'accord... Ce n'est pas la même chose !

Eh non...


Comparaison de l'intégrité référentielle avec la propriété de champ "Limité à liste"

Donc, le truc du "Limiter à liste" est intéressant, mais évidemment, s'il y avait des pays fantaisistes, ça ne nous aurait été d'aucun secours !

Eh non... Tandis que maintenant, c'est sût et certain, ça ne peux pas arriver. Votre table est vraiment fiable.

En fait, dans l'absolu, la liste déroulante n'est pas indispensable alors ?

Dans l'absolu, non ! ça n'a rien à voir avec les relations. D'ailleurs, nous avions créé des listes déroulantes sans la moindre relation... Mais par contre, c'est quand même plus sympathique d'en avoir une... Vous imaginez si vous avez une relation avec intégrité référentielle entre T_Client et T_Pays, mais pas de liste déroulante ? Quelle galère ! Il faudrait connaître par coeur tous les pays !

Bon... Hem... On peut résumer ?

Il est possible de créer des relations entre tables de 2 manières : avec ou sans intégrité référentielle. S'il n'y a pas d'intégrité référentielle, les relations ne servent pas à grand chose.
Par contre, quand elle est appliquée, alors, tout est sécurisé : Les 2 champs mis en relation DOIVENT absolument correspondre sans exception.
Pour appliquer l'intégrité référentielle, il faut que le champ qui sert de "source" (Pays de T_Pays dans notre exemple) soit en clé primaire, sinon, ça ne marche pas.

Avez-vous bien compris ?

  1. Toutes les tables de la base de données doivent obligatoirement être reliées entre elles ?
    a. Oui
    b. Non ***
    c. Au contraire, elles ne doivent jamais être reliées

  2. On crée une relation avec intégrité référentielle entre 2 tables quand :
    a. On désire qu'un des champs d'une des 2 tables corresponde exactement avec un champ de l'autre table ***
    b. Les deux tables comprennent le même nombre de champs
    c. Il n'est pas possble d'avoir deux enregistrements identiques
    d.
    Le nombre de tables est supérieur à 12
  3. On peut créer une liste déroulante sur une autre table s'il n'y a pas de relation entre les 2 tables ?
    a. Oui ***
    b. Non
    c. Oui, mais il FAUT que "Limiter à liste" = NON
    d. Oui, mais la liste déroulante doit être locale

  4. Il est possible d'établir une relation avec intégrité référentielle entre 2 tables s'il n'y a aucune clé primaire ?
    a. Oui
    b. Non ***
    c. Le simple fait de créer une relation crée automatiquement la clé primaire


    Pour voir les solutions, il vous suffit de sélectionner le questionnaire ci-dessus : 3 petites étoiles *** apparaîtront en face des bonnes réponse

Exercice

Créez une base de données ClubVacances.MDB, dans laquelle vous créez 4 tables, exactement comme ceci :

(Il est PRIMODIAL que vous recopiez exactement les choses pour le bien de l'exercice (Les erreurs sont voulues) - Nul besoin de créer des listes déroulantes. Bien entendu, une fois que vous avez recopié ces tables, des erreurs vont apparaître qui vont vous empêcher d'établir cette intégrité référentielle : c'est à ce moment-là que vous modifierez vos données en conséquence)

T_Client

NomPrenom SportFavori LangueMaternelle PaysOrigine
Paul Miller Aviron Anglais USA
Marc Despond Tennis de table Anglais Grande-Bretagne
Julien Pidou Aviron Français Canada
Carole Merlet Pétanque Allemand Allemagne

T_Sport

Badminton
Aviron
Ping-Pong
Tennis
Boules
Bowling

T_LangueMaternelle

Français
Anglais
Espagnol
Portugais

T_Pays

U.S.A.
Angleterre
Canada
Allemagne
Portugal
Autriche

L'exercice consiste à lier toutes ces tables AVEC intégrité référentielle, comme ceci :

Téléchargez la solution de l'exercice ici

Si vous n'êtes pas tout à fait certain d'avoir suivi correctement toutes les étapes de cette leçon, vous avez la possibilité de télécharger ici la version de ProFormation.mdb exactement dans l'état ou elle devrait être à la fin de cette leçon.

Avez-vous une question technique concernant cette leçon ? Cliquez ici !
Une remarque sur cette leçon ? Un problème ? Une erreur ? une ambiguité ? Soyez gentil de m'en informer