Quand pouvez-vous supprimer en toute sécurité d'anciennes colonnes de base de données ? La phase de contraction du pattern Expand-Contract

Vous avez migré tout votre code applicatif vers le nouveau format de colonne. Le déploiement s'est déroulé sans accroc. Aucune erreur dans les logs. Votre équipe est prête à nettoyer l'ancien schéma et à passer à la prochaine fonctionnalité.

Mais devriez-vous supprimer cette colonne tout de suite ?

La réponse est presque toujours non. Supprimer des structures de base de données trop tôt est l'une des causes les plus fréquentes d'incidents de production qui semblent surgir de nulle part. Un job batch qui s'exécute une fois par mois, une requête de reporting écrite il y a six mois, ou un service legacy qui ne se réveille que lors du traitement de fin de trimestre peuvent tous échouer silencieusement jusqu'au moment où ils ont réellement besoin de s'exécuter.

La phase finale du pattern expand-contract s'appelle la phase de contraction. Le nom vient de l'idée de réduire ou de supprimer les structures qui ne sont plus utilisées. Mais atteindre cette phase nécessite plus que de simplement confirmer que votre application principale a basculé.

Qui d'autre touche encore à l'ancienne structure ?

Avant de supprimer quoi que ce soit, vous devez répondre à une question : qui d'autre lit ou écrit encore dans l'ancien schéma ?

Votre application principale est peut-être passée à autre chose. Mais il peut y avoir d'autres consommateurs auxquels vous n'avez pas pensé :

  • Un job batch nocturne qui référence encore l'ancienne colonne
  • Des requêtes manuelles exécutées par l'équipe data pour des analyses ad-hoc
  • Un système de reporting qui génère des PDF mensuels à partir de l'ancienne table
  • Un outil interne déployé il y a six mois et jamais mis à jour
  • Une intégration tierce qui envoie des données dans l'ancien format

Ces dépendances sont faciles à manquer car elles ne suivent pas le même cycle de déploiement que votre application principale. Elles ne sont peut-être même pas dans le même dépôt. Certaines ne sont peut-être pas du code du tout - ce peuvent être des scripts SQL sauvegardés sur l'ordinateur portable de quelqu'un.

Comment détecter les dépendances cachées

Le moyen le plus simple de trouver ces dépendances est de consulter les logs de votre base de données. Les bases de données comme PostgreSQL, MySQL et Oracle enregistrent toutes les requêtes qui sont exécutées contre elles. Vous pouvez filtrer pour trouver les requêtes qui référencent la colonne ou la table que vous prévoyez de supprimer.

Le diagramme suivant résume le processus de décision pour déterminer s'il est sûr de supprimer une ancienne colonne :

flowchart TD A[Plan de suppression d'une ancienne colonne ?] --> B{Existe-t-il un job batch ?} B -->|Oui| C[Ne pas supprimer pour l'instant] B -->|Non| D{Existe-t-il une requête de reporting ?} D -->|Oui| C D -->|Non| E{Existe-t-il un outil interne ?} E -->|Oui| C E -->|Non| F{Existe-t-il une intégration tierce ?} F -->|Oui| C F -->|Non| G[Supprimer la colonne]

Si votre base de données ne journalise pas les requêtes par défaut, vous pouvez l'activer temporairement. PostgreSQL dispose de pg_stat_statements pour le suivi des statistiques de requêtes. MySQL a le Performance Schema. Les deux peuvent vous montrer quelles requêtes touchent encore l'ancienne structure.

Une deuxième approche consiste à surveiller les erreurs après le basculement de votre application. Si quelque chose tente encore d'écrire dans l'ancienne colonne, vous verrez probablement des erreurs dans les logs applicatifs. Mais cela ne capture que les consommateurs actifs. Un script qui s'exécute une fois par trimestre peut ne pas déclencher d'erreur avant des mois.

C'est pourquoi la période d'attente avant la suppression est importante. Certaines équipes attendent un cycle de déploiement complet - généralement deux semaines après que toutes les applications ont basculé. D'autres attendent plus longtemps, surtout lorsqu'il y a des requêtes manuelles ou des rapports exécutés par des équipes non techniques. Il n'y a pas de règle universelle, mais plus vous avez de dépendances non contrôlées, plus vous devez attendre.

La suppression proprement dite

Une fois que vous êtes sûr qu'aucune dépendance ne subsiste, vous pouvez procéder à la suppression. Les commandes SQL sont simples :

Voici un exemple pratique du SQL que vous exécuteriez, ainsi qu'une requête pour vérifier qu'aucun autre objet de la base de données ne dépend encore de la colonne :

-- D'abord, vérifier les vues, fonctions ou déclencheurs qui référencent la colonne
SELECT DISTINCT
    OBJECT_SCHEMA,
    OBJECT_NAME,
    OBJECT_TYPE
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%old_column_name%'
UNION
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    'VIEW'
FROM INFORMATION_SCHEMA.VIEWS
WHERE VIEW_DEFINITION LIKE '%old_column_name%';

-- Une fois la sécurité confirmée, supprimer la colonne
ALTER TABLE users DROP COLUMN old_legacy_status;

-- Nettoyer les index qui n'existaient que pour l'ancienne colonne
DROP INDEX IF EXISTS idx_old_status ON users;

Exécutez d'abord la vérification des dépendances, puis procédez à la suppression. Si la vérification retourne des lignes, vous avez trouvé un consommateur caché qui doit être mis à jour avant de pouvoir supprimer en toute sécurité.

  • Pour une colonne : ALTER TABLE ... DROP COLUMN
  • Pour une table : DROP TABLE
  • Pour une contrainte : ALTER TABLE ... DROP CONSTRAINT

Mais l'ordre compte. Supprimez d'abord les colonnes ou les tables les moins susceptibles d'être utilisées, puis attendez quelques jours avant de supprimer le reste. Cette approche par étapes vous offre un filet de sécurité. Si quelque chose se casse après la première suppression, vous avez encore le temps de réagir avant que les structures les plus critiques ne disparaissent.

N'oubliez pas les index et les déclencheurs

Un point souvent négligé est le nettoyage des objets de base de données associés. Les index qui n'existaient que pour l'ancienne colonne doivent être supprimés. Les déclencheurs qui référencent l'ancienne table doivent être retirés. Si vous les laissez derrière vous, votre base de données accumule du poids mort qui peut ralentir les écritures et compliquer les migrations futures.

Une liste de contrôle rapide avant de finaliser la phase de contraction :

  • Confirmer qu'aucune requête active ne touche l'ancienne structure (vérifier les logs sur au moins un cycle complet)
  • Vérifier que tous les jobs batch, rapports et scripts manuels ont été mis à jour
  • Supprimer les index qui ne servaient que l'ancienne colonne
  • Retirer les déclencheurs qui référencent l'ancienne table
  • Supprimer par étapes : d'abord le moins risqué, attendre, puis continuer
  • Surveiller les erreurs applicatives pendant 24 à 48 heures après chaque suppression

Le véritable enseignement

La phase de contraction ne concerne pas la vitesse. Elle concerne la confiance. Supprimer un ancien schéma trop tôt introduit un risque difficile à détecter jusqu'à ce qu'il soit trop tard. La période d'attente supplémentaire n'est pas du temps perdu - c'est votre tampon de sécurité contre les dépendances cachées dont vous ignoriez l'existence.

Une fois l'ancien schéma supprimé, le pattern expand-contract est terminé. Vous avez ajouté la nouvelle structure, migré tous les consommateurs et supprimé l'ancienne en toute sécurité sans provoquer d'incident de production. C'est tout l'intérêt du pattern : rendre les modifications de base de données suffisamment sûres pour que votre équipe ne les redoute pas.