Расширьте схему заказов для выбора пункта выдачи

MySQLBeginner
Практиковаться сейчас

Введение

Небольшой магазин добавляет пункты выдачи. Старый клиент оформления заказа передаёт ID заказа, покупателя, целое число центов и заметку; новый также передаёт код пункта выдачи. Существующие заказы и связи с их товарными позициями должны остаться пригодными к работе. Значение по умолчанию обеспечивает совместимость при пропуске столбца, но не говорит, где покупатель исторического заказа действительно выбрал получение.

Вы подготовите expand.sql и расширенную действующую таблицу заказов, используете оба подготовленных клиента, затем увидите настоящую границу между транзакциями данных и DDL MySQL. Предварительно нужны базовые навыки навигации в терминале, MySQL SELECT/WHERE, INSERT/UPDATE, знание столбцов, первичных ключей и значений по умолчанию. Разработка на Python или создание приложения не требуются. Это независимое занятие предоставляет собственный отдельный Oracle MySQL и Terminal; общая служба базы данных с ним не связана.

Работайте только в /home/labex/project/pickup-desk. Вы можете добавить описанный столбец пункта выдачи в orders и обновлять или расширять только изолированную ddl_demo для демонстрации. Сохраните все исходные ID заказов, покупателей, суммы, заметки, товарные позиции, пункты и таблицы утверждённых соответствий, а также предоставленные инструменты. Разрешено добавить только три названных ниже учебных заказа. Это контролируемое окно обслуживания, а не миграция онлайн, без блокировок или без простоя. Оценка времени автором включает чтение и обычные ошибки; время прохождения новичками не измерялось.

Расширьте схему, сохранив работу обоих клиентов

На этом шаге вы создадите обычный заказ старым клиентом, добавите совместимый столбец пункта выдачи и прочитаете настоящие заказы обеих версий клиента.

Начните во вкладке Terminal, в приглашении оболочки. cd меняет текущий каталог; абсолютный путь работает из любого начального каталога. ./shop запускает подготовленную команду из этого каталога. Это команды оболочки, а не ввод в приглашении MySQL:

cd /home/labex/project/pickup-desk
./shop status
./shop points

Исходные записи заказов — 101 / Sam / 2100, 102 / Sam / 3400 и 103 / Lee / 0, со своими заметками и товарными позициями. Два заказа Sam имеют разные идентификаторы. Суммы — целое число центов, ноль допустим. status и show читают фактически сохранённые значения; они никогда не мигрируют запись и не подставляют вариант получения.

Подготовленный старый клиент принимает old order_id customer total_cents sku quantity. Он вставляет запись заказа с явными именами старых столбцов и товарную позицию в одной штатной транзакции. Успешный вызов фиксируется; ошибка SQL MySQL останавливает пакет и закрывает соединение, откатывая ожидающие фиксации изменения данных. Создайте разрешённый обычный заказ, затем прочитайте его:

./shop old 201 Mina 1600 MUG 1
./shop show 201

Его запись содержит ID 201, Mina, 1600 и Created by legacy client; товарная позиция содержит MUG в количестве 1. Возвращённое pickup_column: false сообщает, что это поле ещё не внедрено. Новый клиент имеет те же аргументы, после которых идёт код пункта выдачи. Следующая команда намеренно должна завершиться штатной ошибкой 1054 — неизвестный столбец pickup_code — и ненулевым статусом завершения. Она не должна оставить запись заказа или товарную позицию:

./shop new 203 Pia 1900 CARD 2 garden
./shop show 203

Чтение показывает пустые header/items. Отсутствующий столбец — ошибка схемы, а не неизвестный код пункта выдачи или успешно оформленный пустой заказ.

Добавьте новый столбец, допускающий NULL, с явным значением по умолчанию counter. ALTER TABLE меняет определение; ADD COLUMN добавляет поле. VARCHAR(16) хранит короткий код пункта выдачи. NULL временно допускает явное неизвестное значение на этапе расширения. DEFAULT 'counter' предоставляет значение для совместимости, когда старый клиент пропускает столбец. Оно также появляется в ранее существовавших строках после расширения, поэтому не доказывает исторический выбор. Следующее независимое занятие обрабатывает утверждённую историю перед ужесточением итоговых правил.

Сохраните полный SQL-файл. cat > expand.sql заменяет этот один файл. Маркер here-document 'SQL' в кавычках заставляет оболочку буквально копировать строки до последнего отдельного SQL. Точка с запятой завершает каждую инструкцию SQL:

cat > expand.sql <<'SQL'
ALTER TABLE orders ADD COLUMN pickup_code VARCHAR(16) NULL DEFAULT 'counter';
SQL

apply выполняет сохранённый файл без изменений в одном пакетном соединении штатного MySQL с ролью миграции курса. Он не определяет варианты получения за вас, не заполняет автоматически выбор пункта выдачи в исторических заказах и не исправляет недостающий SQL:

./shop apply expand.sql
./db -e "SHOW COLUMNS FROM orders;"

./db подключается к отдельной базе данных этого курса; -e выполняет следующую строку SQL в кавычках и завершает работу. Двойные кавычки удерживают пробелы и точку с запятой внутри одного аргумента оболочки. Прочитайте тип столбца пункта выдачи, допустимость NULL и значение по умолчанию: varchar(16), YES, counter. Другие исходные поля остаются на месте.

Снова используйте старый клиент и повторите ранее отклонённый новый заказ:

./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

Заказы 201 и 202 содержат фактически сохранённое значение по умолчанию counter; 203 — garden. Все записи заказов и настоящие товарные строки сохранены. Исходные три заказа теперь показывают counter как значение по умолчанию этапа расширения; не утверждайте, что все исторические заказы получали там. Подготовленная таблица утверждённых соответствий остаётся нетронутой.

При обычной опечатке ./shopp выполните ls и используйте правильное имя ./shop. Если SQL сообщает о синтаксической ошибке, изучите cat expand.sql, исправьте полную сохранённую инструкцию и примените её только при всё ещё отсутствующем столбце. Ошибка 1060 при повторном расширении означает, что столбец уже существует; изучите SHOW COLUMNS вместо удаления столбца или сброса базы данных. Повтор успешного заказа клиента даёт ошибку дублирующегося ID: используйте show для существующего заказа, а не придумывайте другой ID. Сохраните названные разрешённые заказы и исходные данные.

Посмотрите, чего не может отменить откат

На этом шаге вы увидите границу штатного ALTER на отдельной демонстрационной таблице, сохранив систему заказов нетронутой.

Продолжайте во вкладке Terminal, в /home/labex/project/pickup-desk. ddl_demo — явно одноразовая учебная таблица из одной строки, отдельная от всех заказов. Её исходная заметка — original:

./db -e "SELECT * FROM ddl_demo;"

Транзакция объединяет изменения данных до COMMIT или ROLLBACK. START TRANSACTION начинает её; UPDATE меняет выбранную строку; ROLLBACK обычно отбрасывает её незафиксированные изменения данных. DDL MySQL — язык определения данных, включая ALTER TABLE — имеет границу неявной фиксации. ALTER фиксирует предшествующую работу перед изменением определения и не отменяется последующим пользовательским ROLLBACK. Восстановление атомарной DDL — не то же самое, что возможность пользовательского отката DDL.

Следующий файл намеренно меняет только эту демонстрационную заметку перед добавлением целочисленного столбца extra, допускающего NULL. Затем он запрашивает ROLLBACK. Перед запуском предположите, сохранятся ли заметка и новый столбец:

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;"

В строке по-прежнему заметка committed before ALTER, а extra равно NULL. SHOW COLUMNS всё ещё перечисляет extra. Прежнее изменение данных UPDATE было зафиксировано ALTER, и новое определение тоже сохранилось. Успешное завершение ROLLBACK их не отменило. Это фактическое поведение сервера, а не выдуманный файл вывода.

Снова прочитайте настоящие заказы:

./shop show 101
./shop show 201
./shop show 203

Их исходные значения записей заказов, заметки, товарные позиции и сохранённые коды пунктов выдачи остаются на месте. Никогда не проводите эту демонстрацию на заметке заказа. Настоящая миграция отделяет транзакционное заполнение исторических данных от последующего ужесточающего DDL и соответственно планирует границы обслуживания и восстановления; помещение каждого ALTER внутрь BEGIN не обеспечивает автоматический откат.

Демонстрационный файл — одноразовый скрипт из указанного исходного определения. Если случайно выполнить его дважды, extra уже существует. Изучите настоящее определение демонстрационной таблицы и строку; не удаляйте таблицу, чтобы второй запуск выглядел новым. Восстановите файл с опечаткой копированием полного блока до первого успешного применения. Занятие завершается совместимым расширением и достоверным наблюдением DDL, а не заявлением о внедрении при непрерывном рабочем трафике.

Резюме

Вы выполнили совместимое расширение таблицы заказов, увидели настоящие записи старого и нового клиентов и сохранили исходные детали заказов. Изолированный эксперимент со штатными командами показал, почему успешный ROLLBACK не отменяет ALTER или предшествующее зафиксированное изменение данных. Исторические варианты получения всё ещё требуют утверждённой таблицы соответствий, изучаемой далее.