Pourquoi les déploiements de base de données sont plus complexes que les déploiements d'application

Vous avez passé la semaine à déployer du code applicatif. Nouvelle fonctionnalité, ancien processus arrêté, nouveau processus démarré. Si quelque chose casse, vous revenez à la version précédente. Le cycle entier prend quelques minutes. C'est rassurant car le code est remplaçable.

Puis arrive une migration de base de données. Une nouvelle colonne doit être ajoutée. Une table doit être renommée. Vous exécutez le script de migration, et soudain la base de production a une structure différente. L'application fonctionne d'abord correctement, mais une heure plus tard, quelqu'un signale des données manquantes dans un rapport. Vous tentez d'annuler la migration, mais les données transformées pendant la migration ne sont pas revenues proprement. Certaines lignes ont encore la nouvelle structure. Certaines anciennes valeurs ont disparu.

C'est le moment où de nombreuses équipes réalisent que le déploiement de base de données n'est pas simplement un « déploiement pour un autre type de chose ». C'est un problème fondamentalement différent.

Le code est jetable, les données ne le sont pas

Quand vous avez appris à construire des applications, vous considériez probablement une application comme un ensemble de code. Vous écrivez du code, l'exécutez, voyez le résultat, et modifiez le code à nouveau si quelque chose ne va pas. Si une nouvelle version ne fonctionne pas, vous revenez à la version précédente. Ce processus semble léger car il n'y a pas de conséquences à long terme. Un code erroné peut être jeté, remplacé ou réécrit de zéro.

Mais dès qu'une application est utilisée par d'autres personnes, quelque chose grandit à ses côtés : les données. Données utilisateur, données de transaction, données de commande, historiques. Ces données ne sont pas simplement le contenu d'une base. Les données sont l'enregistrement de ce qui s'est déjà produit dans l'entreprise. Chaque ligne d'une table stocke quelque chose de précieux. Si des données sont perdues, réécrire le code ne les fera pas revenir. Les données perdues ne peuvent pas être régénérées.

C'est la différence fondamentale entre le code applicatif et une base de données. Le code applicatif peut être traité comme un artefact remplaçable. Vous pouvez supprimer un dossier de projet, le recloner depuis un dépôt, et l'application fonctionnera exactement comme avant. Mais une base de données n'est pas comme ça. Une base de données stocke un état, c'est-à-dire la condition actuelle des données métier. Cet état est formé par l'accumulation d'opérations déjà effectuées. Si la base de données est supprimée, l'état disparaît. Il n'y a pas de git clone qui puisse restaurer les données clients collectées pendant un an.

L'impact du déploiement

L'effet de cette différence devient immédiatement apparent lors du déploiement. Quand vous déployez une nouvelle version d'une application, vous envoyez le dernier code sur le serveur, arrêtez l'ancien processus et démarrez le nouveau. Si la nouvelle version a des problèmes, vous pouvez revenir en arrière en restaurant la version précédente. L'application fonctionnera comme avant la mise à jour.

Mais quand un déploiement de base de données modifie la structure des tables, les données existantes sont affectées. Une nouvelle colonne peut être remplie avec des valeurs par défaut. Les types de données peuvent changer. Les anciennes données peuvent devoir être transformées. Si ces changements causent des problèmes, revenir en arrière n'est pas aussi simple que d'échanger des versions de code. Les données qui ont déjà été modifiées ne reviennent pas automatiquement à leur forme originale.

Considérez une migration simple qui ajoute une colonne et la remplit avec des données :

-- Migration forward
ALTER TABLE users ADD COLUMN age INT;
UPDATE users SET age = 25 WHERE age IS NULL;
-- Script de rollback
ALTER TABLE users DROP COLUMN age;

Si la migration forward a été exécutée et que l'application a commencé à écrire de nouveaux âges, le rollback supprime la colonne et ces nouvelles valeurs sont perdues. Contrairement au code applicatif, vous ne pouvez pas simplement redéployer l'ancienne version pour récupérer les données perdues.

C'est pourquoi de nombreuses équipes deviennent prudentes avec les déploiements de base de données. Elles peuvent échanger rapidement des versions d'application plusieurs fois par jour, mais hésitent à exécuter une migration de base de données à chaque déploiement. Non pas parce que les migrations sont techniquement difficiles, mais parce que les conséquences sont différentes. Un code erroné peut être corrigé en le réécrivant. Des données erronées peuvent prendre des jours à corriger, et parfois ne peuvent pas être restaurées exactement comme avant.

Comment cela modifie votre processus de déploiement

La différence entre le code et les données affecte la façon dont vous concevez votre processus de déploiement. Pour les applications, vous devez principalement vous assurer que le nouveau code peut s'exécuter. Pour les bases de données, vous devez garantir que les changements structurels n'endommagent pas les données existantes, ne perturbent pas l'application en cours d'exécution, et peuvent toujours être annulés si quelque chose tourne mal.

Voici les implications pratiques :

Les déploiements d'application sont additifs. Vous ajoutez du nouveau code, supprimez l'ancien, et le système continue. L'ancienne version est toujours disponible dans votre dépôt ou stockage d'artefacts.

Les déploiements de base de données sont transformateurs. Vous modifiez la structure des données existantes. L'ancienne structure disparaît une fois la migration exécutée. Même si vous avez une sauvegarde, la restaurer signifie perdre toutes les données créées après la sauvegarde.

Les rollbacks d'application sont peu coûteux. Vous pointez le répartiteur de charge vers l'ancienne version, ou redémarrez l'ancien processus. L'état de l'application est déterminé par le code qui s'exécute.

Les rollbacks de base de données sont coûteux. Vous devez écrire une migration inverse qui transforme les données pour revenir à leur structure précédente. Cette migration inverse doit être testée. Elle peut échouer si de nouvelles données ont été ajoutées et ne correspondent pas à l'ancienne structure. Et si la migration forward a transformé les données de manière irréversible (par exemple, en concaténant prénom et nom dans une seule colonne), la migration inverse peut perdre des informations.

Le vrai risque n'est pas technique

De nombreuses équipes traitent les migrations de base de données comme un problème purement technique. Elles écrivent des scripts de migration, les testent en préproduction, et les exécutent en production. Quand quelque chose tourne mal, elles blâment le script de migration ou l'outil de base de données.

Mais le vrai risque est souvent organisationnel. Une migration de base de données touche des données qui appartiennent à de vrais utilisateurs. Une erreur peut corrompre des enregistrements clients, des données financières ou des journaux de conformité. L'équipe qui exécute la migration peut ne pas comprendre pleinement comment les données sont utilisées par d'autres systèmes. Un renommage de colonne peut casser une requête de rapport qui s'exécute une fois par mois. Un changement de type de données peut faire échouer silencieusement un service legacy.

C'est pourquoi les déploiements de base de données nécessitent un niveau d'attention différent. La complexité technique est gérable. La complexité organisationnelle est ce qui ralentit les équipes.

Liste de contrôle pratique pour les déploiements de base de données

Avant d'exécuter une migration de base de données en production, considérez ces vérifications :

  • La migration peut-elle être annulée ? Écrivez et testez le script de rollback avant d'exécuter la migration forward.
  • La migration va-t-elle casser l'application actuelle ? Si l'application lit une colonne que vous renommez, l'application échouera jusqu'à ce qu'elle soit également mise à jour.
  • La migration peut-elle s'exécuter pendant que l'application est en ligne ? Certaines migrations verrouillent des tables, ce qui peut entraîner des temps d'arrêt.
  • Y a-t-il une sauvegarde ? Effectuez une sauvegarde avant toute migration qui transforme des données.
  • Qui doit être informé ? Prévenez les équipes qui consomment ces données, y compris les rapports, l'analytique et la data science.

Ce qu'il faut retenir

Le code applicatif est jetable. Vous pouvez le jeter, le réécrire et déployer une nouvelle version sans rien perdre d'important. Les données de base de données ne sont pas jetables. Chaque migration modifie quelque chose qui ne peut pas être facilement recréé.

Traitez les déploiements de base de données avec la même rigueur que les incidents de production. Écrivez des scripts de rollback. Testez les migrations avec des données réalistes. Communiquez avec les équipes qui dépendent des données. Et ne présumez jamais qu'une migration est sûre simplement parce qu'elle a réussi en préproduction.

La différence entre le code et les données n'est pas un détail technique. C'est la raison pour laquelle les déploiements de base de données méritent leur propre processus, leur propre stratégie de test et leur propre évaluation des risques.