ressources-et-pratique

Foreign keys et intégrité référentielle : guide complet SQL

Foreign keys et intégrité référentielle : définition, syntaxe, bonnes pratiques. Exemples PostgreSQL, MySQL, SQLite pour garantir la cohérence des données.

Les clés étrangères (foreign keys) sont les garantes de l’intégrité référentielle dans vos bases de données relationnelles. Guide complet avec exemples PostgreSQL, MySQL, SQLite.

Résumé

Une clé étrangère (foreign key) est une contrainte qui lie une colonne d’une table à la clé primaire (ou une clé unique) d’une autre table. Elle assure l’intégrité référentielle : impossible d’insérer une commande sans client existant, ou de supprimer un client sans traiter ses commandes. Ce guide explique la syntaxe SQL standard, les options de mise à jour (ON DELETE, ON UPDATE) – CASCADE, RESTRICT, SET NULL – et les différences entre PostgreSQL, MySQL et SQLite. Des exemples concrets illustrent comment créer, modifier et supprimer des foreign keys. Enfin, les bonnes pratiques (indexation, nommage, choix des actions) sont détaillées.

1. Définition : qu’est-ce qu’une clé étrangère ?

Une clé étrangère (foreign key) est une contrainte d’intégrité qui lie deux tables.

Schéma de deux tables : clients (id PK) et commandes (id PK, client_id FK vers clients.id)

Figure 1 — Relation entre table clients (parent) et commandes (enfant) via une clé étrangère.

  • La table parent (référencée) contient une clé primaire (ou unique).
  • La table enfant (référençante) contient une colonre qui référence la clé primaire du parent.
  • La contrainte garantit que chaque valeur de la clé étrangère existe bien dans la table parent (ou soit NULL si autorisé).

Exemple : une table commandes a une colonne client_id qui doit correspondre à un id existant dans la table clients. On ne peut pas créer une commande pour un client inexistant.

2. Pourquoi l’intégrité référentielle est cruciale

Sans clé étrangère, on peut insérer des « orphelins » : une commande dont le client a été supprimé, ou un client qui n’existe pas. La cohérence des données est alors brisée.

Problèmes courants sans foreign keys

  • Données orphelines : des lignes qui référencent des lignes parent disparues.
  • Incohérence des rapports : des sommes qui ne correspondent plus.
  • Suppression accidentelle : on peut supprimer un client sans supprimer ses commandes (impossible avec CASCADE ou RESTRICT).

L’intégrité référentielle protège contre ces anomalies.

3. Syntaxe SQL standard

Création d’une table avec foreign key

CREATE TABLE clients (
    id INT PRIMARY KEY,
    nom VARCHAR(100)
);

CREATE TABLE commandes (
    id INT PRIMARY KEY,
    client_id INT,
    date_commande DATE,
    FOREIGN KEY (client_id) REFERENCES clients(id)
);

Ajout d’une clé étrangère sur une table existante

ALTER TABLE commandes
ADD CONSTRAINT fk_commandes_client
FOREIGN KEY (client_id) REFERENCES clients(id);

Suppression d’une clé étrangère

ALTER TABLE commandes DROP CONSTRAINT fk_commandes_client;

Contraintes sur plusieurs colonnes (clé composite)

CREATE TABLE details (
    commande_id INT,
    produit_id INT,
    quantite INT,
    PRIMARY KEY (commande_id, produit_id),
    FOREIGN KEY (commande_id) REFERENCES commandes(id),
    FOREIGN KEY (produit_id) REFERENCES produits(id)
);

4. Options ON DELETE et ON UPDATE

Ces options définissent le comportement quand une ligne parent est supprimée (DELETE) ou que sa clé primaire est mise à jour (UPDATE).

OptionEffet sur les enfants
ON DELETE NO ACTION (par défaut)Empêche la suppression du parent si des enfants existent.
ON DELETE RESTRICT (similaire)Idem, vérifiée immédiatement.
ON DELETE CASCADESupprime automatiquement tous les enfants lorsque le parent est supprimé.
ON DELETE SET NULLMet la colonne foreign key à NULL (si autorisée).
ON DELETE SET DEFAULTMet la colonne foreign key à sa valeur par défaut.

Exemple avec CASCADE :

CREATE TABLE commandes (
    id INT PRIMARY KEY,
    client_id INT,
    FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE CASCADE
);

Si on supprime un client, toutes ses commandes sont automatiquement supprimées.

Diagramme illustrant la suppression en cascade : client supprimé → commandes supprimées → détails commande supprimés

Figure 2 — Comportement de ON DELETE CASCADE : la suppression d’un client entraîne la suppression des commandes et des détails.

Recommandations

  • CASCADE : utile pour les relations de composition (ex: commandes dépendent du client). À utiliser avec précaution.
  • RESTRICT / NO ACTION : protège contre les suppressions accidentelles (par défaut le plus sûr).
  • SET NULL : quand la relation est optionnelle (par exemple, un « ancien client » conserve ses commandes mais plus de lien actif).

5. Implémentations spécifiques

PostgreSQL

  • Supporte toutes les options standard.
  • Permet les foreign keys vers des colonnes UNIQUE, pas seulement PRIMARY KEY.
  • Les contraintes peuvent être désactivées temporairement avec SET CONSTRAINTS ... DEFERRED.
-- PostgreSQL
ALTER TABLE commandes
ADD CONSTRAINT fk_client
FOREIGN KEY (client_id) REFERENCES clients(id)
ON DELETE CASCADE;

MySQL (InnoDB uniquement)

  • Seul le moteur InnoDB gère les foreign keys (MyISAM ignore la syntaxe sans erreur).
  • MySQL accepte ON DELETE SET DEFAULT mais uniquement avec certains moteurs.
  • Les foreign keys nécessitent que les colonnes soient indexées (création automatique de l’index si absent).
-- MySQL / InnoDB
CREATE TABLE commandes (
    id INT PRIMARY KEY,
    client_id INT,
    FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE RESTRICT
) ENGINE=InnoDB;

SQLite

  • Gère les foreign keys, mais désactivées par défaut (il faut activer PRAGMA foreign_keys = ON;).
  • Supporte ON DELETE CASCADE, SET NULL, RESTRICT, NO ACTION.
  • Ne supporte pas ON UPDATE SET DEFAULT.
-- SQLite
PRAGMA foreign_keys = ON;
CREATE TABLE commandes (
    id INTEGER PRIMARY KEY,
    client_id INTEGER,
    FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL
);

Comparaison rapide

FonctionnalitéPostgreSQLMySQL (InnoDB)SQLite
Support standardExcellenteBonneBonne (activé manuellement)
Index automatiqueNonOuiNon
ON DELETE SET DEFAULTOuiOuiNon
Désactivation temporaireOui (DEFERRED)NonNon (PRAGMA global)

6. Bonnes pratiques

Nommez explicitement vos contraintes

-- Mauvais
FOREIGN KEY (client_id) REFERENCES clients(id)

-- Bon
CONSTRAINT fk_commandes_client_id FOREIGN KEY (client_id) REFERENCES clients(id)

Un nom clair facilite la lecture et le DROP.

Indexez les colonnes foreign key

Dans PostgreSQL et SQLite, les foreign keys ne créent pas automatiquement d’index. Une requête de jointure sera plus lente sans index. Ajoutez un index manuellement :

CREATE INDEX idx_commandes_client_id ON commandes(client_id);

Choisissez l’option ON DELETE adaptée

  • RESTRICT pour éviter les suppressions accidentelles (le plus courant).
  • CASCADE pour les relations de dépendance forte (commande-lignes de commande).
  • SET NULL pour les relations optionnelles.

Évitez les chaînes de CASCADE trop longues

Une cascade sur 5-6 niveaux peut entraîner des suppressions massives non intentionnelles.

Testez avec des données de développement

Avant d’appliquer une contrainte en production, testez son comportement sur un environnement de développement. Les violations d’intégrité peuvent faire échouer des migrations.

À retenir : Les foreign keys sont un filet de sécurité. Elles ne ralentissent pas significativement une application bien conçue. Les bases de données sans contraintes finissent par avoir des incohérences qui coûtent très cher à corriger.

Revenir au guide complet

Cet article fait partie du guide complet sur le Data Engineering.

Articles connexes

FAQ

Qu’est-ce qu’une clé étrangère (foreign key) ?

Une clé étrangère est une colonne (ou groupe de colonnes) qui établit un lien entre deux tables. Elle fait référence à la clé primaire d’une autre table (la table parent). Elle garantit l’intégrité référentielle : toute valeur insérée dans la clé étrangère doit déjà exister dans la clé primaire de la table parent.

Quelle est la différence entre clé primaire et clé étrangère ?

Une clé primaire identifie de manière unique chaque ligne d’une table ; elle ne peut pas être NULL. Une clé étrangère référence une clé primaire (ou une clé unique) d’une autre table ; elle peut accepter des valeurs NULL si la contrainte le permet.

Que se passe-t-il si on insère une valeur non référencée dans une foreign key ?

La base de données rejette l’insertion et lève une erreur de violation d’intégrité référentielle. C’est le comportement par défaut qui protège la cohérence des données.

Que signifie ON DELETE CASCADE ?

ON DELETE CASCADE est une option qui, lorsqu’une ligne parent est supprimée, entraîne automatiquement la suppression des lignes enfants qui référencent cette ligne. Utile pour maintenir la cohérence, mais à utiliser avec précaution.

Faut-il toujours créer des foreign keys ?

Oui, dans une base de données relationnelle normale, elles sont fortement recommandées pour garantir l’intégrité des données. Dans des environnements très volumineux (data warehouses, lacs de données) ou certaines architectures NoSQL, les foreign keys peuvent être relâchées pour la performance, mais cela augmente les risques d’incohérence.

Les foreign keys ralentissent-elles les bases de données ?

Légèrement sur les opérations d’écriture (INSERT, UPDATE, DELETE) car chaque modification vérifie la contrainte. Sur les lectures, l’impact est négligeable. Dans la plupart des applications métier, le bénéfice de la cohérence l’emporte largement sur le léger coût en performance.

Sources

  • PostgreSQL Documentation – Foreign Keys
  • MySQL Reference Manual – InnoDB Foreign Key Constraints
  • SQLite Documentation – Foreign Key Support
  • ISO/IEC 9075 (SQL standard) – Referential integrity

Article mis à jour le 8 juin 2026.