Les clés étrangères

Les clés étrangères

8 mai 2021

La clé étrangère est un champ dans une table pointant vers une clé primaire d'une autre table. Cela permet de relier les informations d'une table aux informations contenues dans une autre table. Son objectif est d'assurer l'intégrité référentielle des données. En d'autres termes, la clé étrangère est forcément reliée à une donnée existante.

Tables d'exemples

Les tables ci-dessous nous serviront d'exemple dans l'article suivant :

Nom de la table : users.

id prenom age
1 Sylvie 34
2 Paul 56
3 Léo 18
4 Sarah 27

Nom de la table : city.

id name
1 Metz
2 Troyes
3 Reims
4 Paris

Relier les deux tables

Maintenant que nous possédons deux tables, nous allons les relier ensemble. L'idée est de relier un utilisateur à une ville. Pour cela, nous devons ajouter une nouvelle colonne dans la table users qui pointera vers la clé primaire de la table city.

Pour faire notre modification, nous utiliserons la commande ALTER TABLE pour ajouter la nouvelle colonne à la table users.

ALTER TABLE users
ADD city_id INT NOT NULL

Le nom de la colonne sera city_id et sera non nullable, c'est-à-dire que notre utilisateur sera obligatoirement relié à une ville.
Par convention, le nom d'une colonne ayant pour objectif de devenir une clé étrangère porte le nom de la table vers laquelle elle pointe, ici city, et le nom de la colonne vers laquelle elle pointera, id, de la table city, soit city_id.

Pour le moment city_id n'est toujours pas une clé étrangère, il reste à la définir comme telle.

ALTER TABLE
FOREIGN KEY (city_id) REFERENCES city(id)

Pour détailler la commande, nous désignons la colonne devenant la clé étrangère FOREIGN KEY (city_id) et nous précisons vers quelle table et quelle colonne elle pointera REFERENCES city(id).

Et maintenant ?

Maintenant, notre table users possède une nouvelle colonne, contenant l'id de l'information vers laquelle elle pointe dans la table city.

id prenom age city_id
1 Sylvie 34 1
2 Paul 56 2
3 Léo 18 2
4 Sarah 27 3

Nom de la table : city.

id name
1 Metz
2 Troyes
3 Reims
4 Paris

Rappel

La clé étrangère assure l'intégrité référentielle des données, ce qui veut dire que je ne peux pas enregistrer l'id numéro 60 si celui-ci n'existe pas dans la table de référence.

Supprimer une clé étrangère

Pour supprimer une clé étrangère, nous garderons l'utilisation de la commande ALTER TABLE.

ALTER TABLE users
DROP FOREIGN KEY city_id

Où placer la clé étrangère ?

En voilà une bonne question ! Tout dépend du type de relation dont vous avez besoin.
Pour cela, il existe quatre cardinalités pour vous aider :

  • OneToMany (1:n)
    Chaque élément de la première table peut être relié à plusieurs éléments de la seconde table. En revanche, les éléments de la seconde table ne peuvent avoir qu'un seul antécédent.
  • ManyToOne (n:1)
    Chaque élément de la première table ne peut avoir qu'un unique élément de la deuxième table en relation. En revanche, un élément de la seconde table peut avoir plusieurs éléments de la première comme antécédent.
  • OneToOne (1:1)
    Chaque élément de la première table est en relation avec un unique élément de la seconde table. La réciproque est vraie : chaque élément de la seconde table n'a qu'un seul élément de la première table comme antécédent.
  • ManyToMany (n:n)
    Chaque élément de la première table peut avoir plusieurs éléments de la seconde en relation et les éléments de la seconde table peuvent aussi avoir plusieurs antécédents.

Reprenons nos tables d'exemples :

Nom de la table : users.

id prenom age city_id
1 Sylvie 34 1
2 Paul 56 2
3 Léo 18 2
4 Sarah 27 3

Nom de la table : city.

id name
1 Metz
2 Troyes
3 Reims
4 Paris

La clé étrangère est sur la table users. Sa cardinalité est ManyToOne : chaque utilisateur est relié à une seule ville, mais une ville peut être reliée à plusieurs utilisateurs.

Prenez bien en compte que la colonne contenant l'id, ne peut stocker qu'une seule valeur. Donc si la clé étrangère se trouve dans la table city, ma relation serait du OneToOne. Le fait d'insérer l'id d'un utilisateur au sein de la table city, reviendrait à bloquer la valeur pour la suite, car celle-ci est déjà reliée.

Si vous voulez qu'un utilisateur puisse être relié à plusieurs villes en même temps et qu'une ville puisse être reliée à plusieurs utilisateurs, la cardinalité à utiliser sera ManyToMany. Dans ce cas, il conviendrait d'utiliser une table associative. Son travail sera d'enregistrer les id des deux tables pour effectuer les relations entre elles. La table associative n'a pas besoin de clé primaire.

Exemple :

Nom de la table : users.

id prenom age
1 Sylvie 34
2 Paul 56
3 Léo 18
4 Sarah 27

Nom de la table : city.

id name
1 Metz
2 Troyes
3 Reims
4 Paris

Nom de la table associative : users_city.

user_id city_id
1 2
2 2
2 4
3 1
4 2

Conseil ?

Je vous conseille de créer toutes vos tables sans clés étrangères dans un premier temps et ensuite de les créer, cela vous évitera bien des ennuis, des erreurs et des oublis.

Faites-le avec des tables vides de données ! Sinon vous pourriez rencontrer des erreurs d'intégrité de relation. En effet, si vos tables sont pleines de données et que vous insérez une clé étrangère, celle-ci se remplira automatiquement de la valeur "0", hors l'id zéro n'existe pas.