Introduction
Un petit magasin ajoute des points de retrait. Son ancien client de commande fournit l’identifiant de commande, le client, les centimes entiers et une note ; un nouveau client fournit aussi un code de retrait. Les commandes existantes et leurs relations avec les articles doivent rester utilisables. Une valeur par défaut maintient la compatibilité lorsqu’une colonne est omise, mais ne nous dit pas où un client historique avait réellement choisi de retirer une commande.
Vous livrerez expand.sql et une table de commandes active étendue, utiliserez les deux clients préparés, puis observerez la véritable frontière entre les transactions de données et le DDL de MySQL. Les prérequis sont la navigation élémentaire dans un terminal et les notions MySQL SELECT/WHERE, INSERT/UPDATE, colonnes, clés primaires et valeurs par défaut. Aucun développement Python ni d’application n’est requis. Cette unité indépendante fournit son propre Oracle MySQL privé et Terminal ; le service de base de données générique est sans rapport.
Travaillez uniquement dans /home/labex/project/pickup-desk. Vous pouvez ajouter la colonne de retrait documentée à orders et mettre à jour/étendre uniquement le ddl_demo isolé pour la démonstration. Préservez tous les identifiants de commande, clients, montants, notes, articles, points et tables d’approbation d’origine, ainsi que les outils fournis. Seules les trois commandes d’entraînement nommées ci-dessous peuvent être ajoutées. Il s’agit d’une fenêtre de maintenance contrôlée, pas d’une migration en ligne, sans verrou ou sans interruption. La durée estimée par l’auteur comprend la lecture et les erreurs ordinaires ; elle n’a pas été chronométrée auprès de débutants.
Étendre le schéma en gardant les deux clients opérationnels
Dans cette étape, vous créerez une commande normale avec l’ancien client, ajouterez une colonne de retrait compatible et lirez de véritables commandes créées par les deux versions de client.
Commencez dans Terminal, à l’invite du shell. cd change le répertoire courant ; le chemin absolu fonctionne depuis n’importe quel répertoire de départ. ./shop exécute une commande préparée de ce répertoire. Ce sont des commandes shell, pas des entrées à une invite MySQL :
cd /home/labex/project/pickup-desk
./shop status
./shop points
Les en-têtes d’origine sont 101 / Sam / 2100, 102 / Sam / 3400 et 103 / Lee / 0, avec leurs propres notes et articles. Les deux commandes Sam sont des identités différentes. Les montants sont des centimes entiers et zéro est valide. status et show lisent les véritables valeurs stockées ; ils ne migrent jamais un enregistrement et ne remplacent pas un choix de retrait.
L’ancien client préparé accepte old order_id customer total_cents sku quantity. Il insère un en-tête avec des noms explicites d’anciennes colonnes et un article dans la même transaction native. Un appel réussi valide ; une erreur SQL native arrête le lot et ferme sa connexion, annulant les modifications de données en attente. Créez la commande ordinaire autorisée, puis lisez-la :
./shop old 201 Mina 1600 MUG 1
./shop show 201
Son en-tête contient l’identifiant 201, Mina, 1600 et Created by legacy client ; son détail contient MUG, quantité 1. Le pickup_column: false renvoyé indique que ce champ n’est pas déployé. Le nouveau client possède les mêmes arguments suivis d’un code de retrait. La commande suivante doit volontairement échouer avec l’erreur native 1054, colonne inconnue pickup_code, et un statut de sortie non nul. Elle ne doit laisser aucun en-tête ni détail :
./shop new 203 Pia 1900 CARD 2 garden
./shop show 203
La lecture montre des listes d’en-têtes et d’articles vides. Une colonne absente est une erreur de schéma, pas un code de retrait inconnu ni une commande vide réussie.
Ajoutez la nouvelle colonne pouvant être NULL avec une valeur par défaut explicite de counter. ALTER TABLE change une définition ; ADD COLUMN ajoute le champ. VARCHAR(16) stocke un court code de retrait. NULL autorise temporairement une valeur inconnue explicite pendant cette phase d’extension. DEFAULT 'counter' fournit la valeur de compatibilité lorsqu’un ancien client omet la colonne. Elle apparaît aussi sur les lignes préexistantes après cette extension ; ce n’est donc pas une preuve du choix historique. Le TP indépendant suivant traite l’historique approuvé avant le renforcement des règles finales.
Enregistrez un fichier SQL complet. cat > expand.sql remplace ce seul fichier. Le marqueur de here-document 'SQL' entre guillemets fait copier les lignes littéralement par le shell jusqu’au SQL final seul. Un point-virgule termine chaque instruction SQL :
cat > expand.sql <<'SQL'
ALTER TABLE orders ADD COLUMN pickup_code VARCHAR(16) NULL DEFAULT 'counter';
SQL
apply exécute le fichier enregistré inchangé dans une connexion native MySQL par lot avec le rôle de migration du cours. Il ne déduit pas les choix de retrait, ne renseigne pas automatiquement les données des commandes historiques et ne répare pas le SQL manquant :
./shop apply expand.sql
./db -e "SHOW COLUMNS FROM orders;"
./db se connecte à la base privée de ce cours ; -e exécute le SQL suivant entre guillemets puis quitte. Les guillemets doubles gardent les espaces et le point-virgule dans un seul argument du shell. Lisez le type, l’autorisation de NULL et la valeur par défaut de la colonne de retrait : varchar(16), YES, counter. Les autres champs d’origine restent présents.
Utilisez à nouveau l’ancien client et réessayez la nouvelle commande précédemment rejetée :
./shop old 202 Omar 1800 BAG 1
./shop new 203 Pia 1900 CARD 2 garden
./shop show 201
./shop show 202
./shop show 203
./shop status
Les commandes 201 et 202 contiennent la véritable valeur par défaut stockée counter ; 203 contient garden. Tous les en-têtes et toutes les véritables lignes d’articles sont conservés. Les trois commandes d’origine affichent maintenant counter comme valeur par défaut de l’extension ; ne prétendez pas que chaque commande historique a été retirée à cet endroit. La table préparée des choix approuvés reste intacte.
Pour une faute ordinaire ./shopp, exécutez ls et utilisez ./shop avec le bon nom. Si SQL signale une erreur de syntaxe, examinez cat expand.sql, corrigez l’instruction complète enregistrée et appliquez-la uniquement si la colonne est encore absente. L’erreur 1060 lors d’une extension répétée signifie que la colonne existe déjà ; examinez SHOW COLUMNS au lieu de la supprimer ou de réinitialiser la base. Répéter une commande client réussie produit une erreur d’identifiant en double : utilisez show pour la commande existante au lieu d’inventer un autre identifiant. Conservez les commandes autorisées nommées et les données d’origine.
Observer ce qu’une annulation ne peut pas défaire
Dans cette étape, vous observerez une frontière native d’ALTER sur une table de démonstration séparée tout en gardant le système de commandes intact.
Continuez dans Terminal, dans /home/labex/project/pickup-desk. ddl_demo est une table pédagogique d’une seule ligne explicitement jetable, distincte de toutes les commandes. Sa note initiale est original :
./db -e "SELECT * FROM ddl_demo;"
Une transaction regroupe les modifications de données jusqu’à COMMIT ou ROLLBACK. START TRANSACTION en démarre une ; UPDATE modifie la ligne sélectionnée ; ROLLBACK abandonne normalement ses modifications de données non validées. Le DDL MySQL (langage de définition de données), dont ALTER TABLE, possède une frontière de commit implicite. ALTER valide le travail précédent avant de changer la définition et n’est pas annulé par un ROLLBACK utilisateur ultérieur. La récupération atomique du DDL ne signifie pas que l’utilisateur peut annuler son DDL.
Le fichier suivant change volontairement uniquement cette note de démonstration avant d’ajouter une colonne entière extra pouvant être NULL. Il demande ensuite ROLLBACK. Prédisez si la note et la nouvelle colonne resteront avant de l’exécuter :
cat > ddl-demo.sql <<'SQL'
START TRANSACTION;
UPDATE ddl_demo SET note='committed before ALTER' WHERE id=1;
ALTER TABLE ddl_demo ADD COLUMN extra INT NULL;
ROLLBACK;
SQL
./shop apply ddl-demo.sql
./db -e "SELECT * FROM ddl_demo;"
./db -e "SHOW COLUMNS FROM ddl_demo;"
La ligne possède toujours la note committed before ALTER et extra est NULL. SHOW COLUMNS liste toujours extra. L’UPDATE de données précédent a été validé par ALTER et la nouvelle définition est également conservée. Le retour réussi de ROLLBACK ne les a pas annulés. C’est un véritable comportement du serveur, pas un fichier de sortie fabriqué.
Relisez les véritables commandes :
./shop show 101
./shop show 201
./shop show 203
Leurs valeurs d’en-tête d’origine, notes, articles et codes de retrait stockés restent présents. N’effectuez jamais cette démonstration sur une note de commande. Une véritable migration sépare le renseignement transactionnel des données historiques du DDL ultérieur de renforcement et planifie sa frontière de maintenance/réparation en conséquence ; placer chaque ALTER dans BEGIN n’offre pas d’annulation automatique.
Le fichier de démonstration est un script à exécuter une seule fois depuis la définition initiale indiquée. Si vous le lancez deux fois par accident, extra existe déjà. Examinez la véritable définition et la ligne de démonstration ; ne supprimez pas la table pour donner l’impression qu’une seconde exécution part de zéro. Restaurez un fichier mal saisi en copiant son bloc complet avant la première application réussie. Cette unité se termine par une extension compatible et une observation fidèle du DDL, pas par une promesse de déploiement sous trafic de production continu.
Résumé
Vous avez livré une extension compatible de la table de commandes, observé les véritables écritures des anciens/nouveaux clients et préservé les détails des commandes d’origine. Une expérience native isolée a montré pourquoi un ROLLBACK réussi ne peut annuler ni ALTER ni la modification de données précédente déjà validée. Les choix de retrait historiques nécessitent encore la correspondance approuvée enseignée ensuite.



