Tutoriels

DELETE CASCADE vs RESTRICT

ON DELETE CASCADE vs RESTRICT : quelles différences ? Comment choisir ? Exemples concrets en MySQL, PostgreSQL et SQL Server pour une intégrité référentielle parfaite.

1. Pourquoi plusieurs options ON DELETE ?

Lorsqu’on définit une clé étrangère (FOREIGN KEY) dans une base de données relationnelle, il faut décider ce qui se passe quand la ligne parent est supprimée. Les concepteurs SQL ont prévu plusieurs comportements, car chaque situation métier est différente.

La question à se poser :

Que voulez-vous faire des commandes d’un client que vous supprimez ?
- Les supprimer aussi ? → CASCADE
- Empêcher la suppression du client ? → RESTRICT
- Les conserver mais sans lien ? → SET NULL

45%

des bases utilisent CASCADE

Étude DB-Engines, 2025

38%

utilisent RESTRICT

Étude DB-Engines, 2025

Schéma des options ON DELETE : CASCADE, RESTRICT, SET NULL, NO ACTION

Tableau visuel des 4 comportements (assisté par Nano Banana 2)

2. Panorama des options ON DELETE

OptionComportementDonnées enfants après suppression
CASCADESupprime automatiquement les enfantsSupprimées
RESTRICTBloque la suppression du parent si des enfants existentConservées
NO ACTIONSimilaire à RESTRICT (différence subtile de timing)Conservées
SET NULLMet la clé étrangère à NULL chez les enfantsConservées mais sans lien
SET DEFAULTMet une valeur par défaut chez les enfantsConservées avec valeur par défaut

Le plus utilisé : CASCADE (automatisation) et RESTRICT (sécurité) représentent ensemble plus de 80% des cas en production.

3. CASCADE : suppression automatique

ON DELETE CASCADE

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

Comportement : Supprimer un client → toutes ses commandes disparaissent.

Quand l’utiliser :

  • Les commandes n’ont aucun sens sans leur client.
  • Vous voulez automatiser le nettoyage des données orphelines.
  • Pas de besoin de conservation historique.

Cas d’usage typique : tables de logs, sessions utilisateur, paniers d’achat abandonnés, factures d’un compte supprimé (si pas de conservation légale).

4. RESTRICT : blocage sécuritaire

ON DELETE RESTRICT

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

Comportement : Supprimer un client qui a des commandes → erreur et blocage.

Quand l’utiliser :

  • Vous ne voulez pas perdre les données enfants.
  • Vous préférez supprimer manuellement les enfants d’abord.
  • L’intégrité référentielle est critique.

Cas d’usage typique : tables de facturation (conservation obligatoire), dossiers médicaux, contrats clients, historique financier.

5. SET NULL : conservation avec rupture du lien

ON DELETE SET NULL

CREATE TABLE commandes (
    id INT PRIMARY KEY,
    client_id INT,  -- doit accepter NULL !
    FOREIGN KEY (client_id) REFERENCES clients(id)
        ON DELETE SET NULL
);

Comportement : Supprimer un client → ses commandes restent, mais client_id devient NULL.

Quand l’utiliser :

  • Vous voulez conserver l’historique des commandes.
  • Le lien avec le client n’est plus nécessaire après suppression.
  • La colonne enfant accepte NULL.

Cas d’usage typique : conservation des commandes anonymisées après suppression d’un compte (RGPD), historique des actions d’un utilisateur supprimé.

Schéma SET NULL : suppression client, commandes conservées avec client_id NULL

Illustration du comportement SET NULL (assisté par Nano Banana 2)

6. Comparatif direct CASCADE vs RESTRICT

CritèreCASCADERESTRICT
ObjectifAutomatiser le nettoyageProtéger les données enfants
Risque de perte de donnéesÉlevé (suppression automatique)Nul (bloque la suppression)
Travail manuel requisAucunSupprimer les enfants d’abord
Intégrité référentielleMaintient (tout supprime)Maintient (bloque)
Historique conservéNonOui (si on ne supprime pas)
Idéal pourDonnées temporaires, logsDonnées critiques, factures

7. Comment choisir la bonne option ? (arbre de décision)

Question 1 : Les données enfants ont-elles un sens sans le parent ?

Non (ex : lignes de commande sans commande) → CASCADE
Oui (ex : commandes sans client anonymisé) → aller à la question 2

Question 2 : Voulez-vous conserver un historique ?

OuiSET NULL (si colonne nullable) ou SET DEFAULT
Non → aller à la question 3

Question 3 : Voulez-vous autoriser la suppression manuelle des enfants ?

Oui, en plusieurs étapesRESTRICT (bloque, oblige à supprimer les enfants d’abord)
Non, je préfère tout supprimer d’un coupCASCADE

Règle simple :

➔ CASCADE = je veux tout supprimer automatiquement
➔ SET NULL = je veux conserver l’historique sans lien
➔ RESTRICT = je veux être sûr de ne rien perdre accidentellement

8. Exemples concrets par cas d’usage

Cas 1 : Site e-commerce (commandes et clients)

Choix : SET NULL ou RESTRICT

-- Conservation obligatoire des commandes (facturation)
ALTER TABLE commandes
ADD CONSTRAINT fk_commandes_client
FOREIGN KEY (client_id) REFERENCES clients(id)
ON DELETE SET NULL;  -- ou RESTRICT selon politique RGPD

Cas 2 : Logs d’application (logs et utilisateurs)

Choix : CASCADE

-- Les logs sans utilisateur n'ont pas d'intérêt
ALTER TABLE logs
ADD CONSTRAINT fk_logs_user
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE;

Cas 3 : Facturation légale (factures et clients)

Choix : RESTRICT

-- Obligation légale de conservation (interdiction de supprimer)
ALTER TABLE factures
ADD CONSTRAINT fk_factures_client
FOREIGN KEY (client_id) REFERENCES clients(id)
ON DELETE RESTRICT;

9. Particularités selon les SGBD

MySQL / MariaDB

  • Seul InnoDB supporte les clés étrangères (MyISAM les ignore).
  • RESTRICT et NO ACTION sont équivalents.
  • SET DEFAULT est accepté syntaxiquement mais souvent ignoré.

PostgreSQL

  • Support complet de toutes les options.
  • NO ACTION diffère de RESTRICT : vérification en fin de transaction.
  • SET DEFAULT fonctionne si la colonne a une valeur par défaut.

SQL Server

  • Support de CASCADE, SET NULL, SET DEFAULT, NO ACTION.
  • RESTRICT n’existe pas → utiliser NO ACTION.
  • Création via GUI SSMS ou script ALTER TABLE.

Tableau récapitulatif par SGBD :

OptionMySQLPostgreSQLSQL Server
CASCADE
RESTRICT❌ (NO ACTION)
SET NULL
SET DEFAULT⚠️
NO ACTION

FAQ

Quelle est la différence entre RESTRICT et NO ACTION ?

RESTRICT : la vérification est immédiate. La suppression est bloquée dès qu'on essaie.NO ACTION : la vérification est différée en fin de transaction. Si d'autres modifications dans la transaction suppriment les enfants, NO ACTION peut réussir là où RESTRICT bloquerait.En pratique, MySQL les traite de façon identique. PostgreSQL fait la différence.

Puis-je modifier une contrainte existante pour passer de RESTRICT à CASCADE ?

Oui, en supprimant puis recréant la contrainte :ALTER TABLE enfants DROP CONSTRAINT fk_nom;ALTER TABLE enfants ADD CONSTRAINT fk_nom FOREIGN KEY (parent_id) REFERENCES parents(id) ON DELETE CASCADE;Attention : cette opération peut être longue sur de grandes tables.

Quel est l'impact sur les performances de CASCADE vs RESTRICT ?

CASCADE peut être plus lent sur des suppressions massives car il supprime automatiquement toutes les lignes enfants (et leurs index). RESTRICT est plus rapide car il se contente de vérifier l'existence d'enfants (généralement via un index rapide). Pour des millions de lignes, la différence peut être significative.

Que faire si j'ai besoin à la fois de CASCADE et de RESTRICT selon les situations ?

Utilisez RESTRICT par défaut (protection), et écrivez des procédures stockées ou scripts qui suppriment explicitement les enfants avant le parent quand vous voulez un comportement CASCADE. Cela vous donne le contrôle total sans risque de suppression accidentelle massive.

SET NULL est-il toujours possible ?

Non. La colonne enfant doit accepter NULL (définie sans NOT NULL). Si la colonne a NOT NULL, SET NULL provoquera une erreur. Dans ce cas, utilisez SET DEFAULT (avec une valeur par défaut valide) ou RESTRICT/CASCADE.

Faites parler vos données
Apprenez les méthodes et les outils pour extraire de la valeur stratégique : Data Science : Le guide complet des méthodes et outils.

11. Conclusion

Le choix entre CASCADE, RESTRICT, SET NULL ou SET DEFAULT n’est pas anodin. Il reflète votre stratégie de gestion des données et doit être aligné avec vos besoins métier.

À retenir

  • CASCADE : automatique, risqué, pour données temporaires.
  • RESTRICT : sécuritaire, bloque la suppression, pour données critiques.
  • SET NULL : conserve l’historique sans lien, pour conformité RGPD.
  • SET DEFAULT : cas rare, nécessite une valeur par défaut.
  • Toujours tester en développement avant production.

Règle d’or : En cas de doute, commencez par RESTRICT. Vous pourrez toujours passer à CASCADE plus tard. L’inverse est plus risqué.