Pourquoi les modifications de schéma de base de données nécessitent la même rigueur que le code
Imaginez ceci : votre équipe vient de déployer une nouvelle fonctionnalité. Le code applicatif fonctionne parfaitement. Mais cinq minutes plus tard, les erreurs commencent à affluer. Une colonne que le nouveau code attend n'existe pas encore. Pire encore, une colonne qui a été supprimée est toujours interrogée par un service plus ancien qui n'a pas été mis à jour. La base de données est dans un état incohérent, et personne ne peut dire exactement ce qui s'est passé ni comment y remédier rapidement.
Ce scénario est plus courant que la plupart des équipes ne l'admettent. La cause racine est presque toujours la même : le schéma de la base de données a été modifié manuellement, sans processus reproductible et sans coordination avec le code applicatif qui en dépend.
La différence fondamentale entre le code et le schéma
Le code applicatif est sans état. Lorsque vous déployez une nouvelle version, les anciens fichiers sont remplacés. Si quelque chose se passe mal, vous pouvez revenir à la version précédente, et le serveur retrouve son état connu. Pas de données résiduelles, pas de dépendances cachées.
Les bases de données sont tout le contraire. Elles sont intrinsèquement avec état. Chaque table, colonne, index et contrainte contient des données accumulées au fil du temps. Lorsque vous modifiez le schéma, vous ne remplacez pas simplement un fichier. Vous modifiez la structure qui contient les données existantes. Une nouvelle colonne peut nécessiter une valeur par défaut pour les lignes existantes. Une colonne supprimée peut retirer des données dont une autre partie du système dépend encore. Un nouvel index peut prendre des minutes ou des heures à construire sur une grande table.
Cette nature avec état rend les modifications de schéma intrinsèquement plus risquées que les modifications de code. Un mauvais déploiement peut être annulé en quelques secondes. Une mauvaise migration peut corrompre les données, casser des requêtes ou faire tomber tout le système. Et parce que la base de données est partagée entre plusieurs services et environnements, le rayon d'explosion est beaucoup plus large.
L'ancienne méthode : manuelle, fragile, non reproductible
Pendant longtemps, les modifications de base de données étaient traitées comme un workflow manuel distinct. Un DBA ou un développeur senior se connectait au serveur de base de données de production, exécutait quelques commandes SQL et attendait. Si la migration réussissait, tant mieux. Si elle échouait, ils essayaient de la réparer sur le moment, souvent sans enregistrement clair de ce qui avait été fait.
Cette approche présente plusieurs problèmes :
- Elle n'est pas reproductible. Les étapes exactes dépendent de qui les exécute, de ce dont ils se souviennent et de ce qu'ils remarquent pendant l'exécution. La même migration peut être effectuée différemment par deux personnes différentes.
- Elle n'est pas auditable. Il n'y a pas d'historique de ce qui a changé, quand et par qui. Si quelque chose se casse des jours plus tard, retracer la cause est presque impossible.
- Elle est fragile. Une seule étape oubliée ou un mauvais ordre d'exécution peut laisser la base de données dans un état incohérent. La récupération devient un exercice manuel sous haute pression.
- Elle bloque la collaboration. Seules quelques personnes ont accès et les connaissances nécessaires pour exécuter les migrations. Le reste de l'équipe ne peut pas examiner, tester ou contribuer aux modifications de schéma.
À mesure que l'équipe grandit et que le système devient plus complexe, cette approche manuelle devient un goulot d'étranglement et un risque. Chaque déploiement impliquant une modification de schéma devient un événement très anxiogène.
Traiter les modifications de schéma comme du code
La solution est simple : gérez les modifications de schéma de base de données avec la même rigueur que vous utilisez pour le code applicatif. Cette pratique s'appelle la migration de schéma, et elle repose sur quelques principes simples.
Écrivez chaque modification sous forme de script de migration. Un script de migration est un fichier contenant les commandes SQL nécessaires pour modifier le schéma de la base de données. Il peut ajouter une colonne, créer une table, ajouter un index ou modifier une contrainte. Chaque script représente un changement logique.
Par exemple, au lieu de vous connecter à la production et d'exécuter :
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
Vous créeriez un fichier de migration comme celui-ci :
-- V001__add_phone.sql
-- Migration forward
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
Et un fichier de rollback correspondant :
-- V001__add_phone_rollback.sql
-- Migration de rollback
ALTER TABLE users DROP COLUMN phone;
Ces fichiers vivent dans votre dépôt, sont examinés dans les pull requests et sont exécutés automatiquement par votre pipeline de déploiement. Pas d'étapes manuelles, pas de commandes oubliées, pas de mystère.
Stockez les scripts de migration dans le même dépôt que le code applicatif. Cela garantit que les modifications de schéma sont versionnées en même temps que le code qui en dépend. Lorsque vous extrayez une version spécifique du code, vous avez également les scripts de migration exacts qui ont été utilisés pour créer le schéma de cette version.
Ne modifiez jamais un script de migration existant. Si vous devez apporter une modification, créez un nouveau script. Cela préserve l'historique intact et garantit que l'ordre d'exécution est clair. Les outils de migration utilisent généralement un numéro de version ou un horodatage pour déterminer quels scripts ont déjà été exécutés et lesquels sont en attente.
Exécutez les migrations dans le cadre du pipeline de déploiement. Tout comme l'exécution de tests ou la construction d'artefacts, l'application des modifications de schéma doit être une étape automatisée de votre pipeline CI/CD. Cela supprime la dépendance à l'exécution manuelle et garantit que chaque environnement reçoit les mêmes modifications dans le même ordre.
Examinez les scripts de migration comme du code. Avant qu'un script de migration ne soit fusionné, il doit passer par une revue de code. Les membres de l'équipe peuvent vérifier les problèmes potentiels : valeurs par défaut manquantes, opérations de longue durée ou modifications qui pourraient casser des requêtes existantes. Cela permet de détecter les problèmes avant qu'ils n'atteignent la production.
Pourquoi c'est important en pratique
Lorsque les modifications de schéma sont gérées comme du code, le processus de déploiement devient prévisible. L'équipe sait exactement ce qui se passera lorsqu'une migration sera exécutée. Ils peuvent d'abord la tester dans un environnement de staging. Ils peuvent revenir en arrière si quelque chose se passe mal, car chaque script de migration a un script de rollback correspondant. Ils peuvent retracer toute modification de schéma jusqu'au commit qui l'a introduite.
Plus important encore, cette approche réduit la peur du déploiement. Les modifications de schéma cessent d'être une activité distincte et à haut risque. Elles deviennent une partie normale du workflow de développement, examinées et testées comme toute autre modification de code. La base de données n'est plus une boîte noire que seules quelques personnes peuvent toucher.
Liste de contrôle pratique pour les migrations de schéma
Avant de fusionner un script de migration, parcourez cette liste de contrôle rapide :
- La migration a-t-elle un script de rollback correspondant ?
- La migration peut-elle être exécutée plusieurs fois sans provoquer d'erreurs (idempotente) ?
- La migration va-t-elle verrouiller les tables pendant longtemps ? Si oui, envisagez le traitement par lots ou l'utilisation d'outils de modification de schéma en ligne.
- Existe-t-il des requêtes ou du code existants qui pourraient être cassés après cette modification ?
- Avez-vous testé la migration sur une copie des données de production ?
- Le script de migration a-t-il été examiné par au moins un autre membre de l'équipe ?
L'essentiel à retenir
Votre schéma de base de données n'est pas un artefact statique. Il évolue en même temps que votre application. Traiter les modifications de schéma comme des opérations manuelles ponctuelles est une recette pour les incidents de production et les frictions d'équipe. En gérant les migrations de schéma avec la même rigueur que le code, vous rendez les modifications de base de données reproductibles, auditées et sûres. La base de données cesse d'être une source de peur et devient simplement une autre partie du système que votre équipe peut modifier en toute confiance.