Les clés étrangères
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.