Методическое руководство для преподавателя СИЭУиП • 4-й семестр

Практическое занятие №10: управление проектом, этап 2

Дисциплина: ОП.08 Основы проектирования баз данных • Раздел: Тема 4. Проектирование структур баз данных (§2.2 с.7–8 программы) • Занятие: №28 (2 академических часа).

1. Педагогическая концепция и целеполагание

Настоящее занятие завершает проектировочно-эксплуатационный цикл учебного курса ОП.08. Если на предыдущих занятиях обучающиеся осваивали нормализацию, создание реляционных объектов, триггеры, индексы и создание клиентских форм с безопасной аутентификацией, то занятие №28 погружает будущих техников-программистов в реальную промышленную практику эволюции структур баз данных (Database Schema Evolution & Versioning).

Ключевая дидактическая цель: Сформировать устойчивые практические навыки управления жизненным циклом и эволюцией схемы БД с использованием профессиональных инструментов миграций (Flyway, Liquibase), версионирования DDL-скриптов, накатов (migrate), безопасных откатов (rollback), применения архитектурного паттерна расширения-сжатия (Expand/Contract) при непрерывном развертывании (Zero-Downtime Deployment) и проведения комплексного регрессионного тестирования клиентских приложений.

Комплекс образовательных задач:

2. Детальный хронометраж учебного занятия

Занятие рассчитано на 2 академических часа. Ниже представлены два регламента проведения: основной (80 минут) и сокращенный (60 минут).

Этап занятия 80 минут 60 минут Содержание деятельности преподавателя и студентов
1. Организационный момент и проблемная мотивация 5 мин
(00:00–00:05)
4 мин
(00:00–00:04)
Приветствие, фиксация присутствующих. Проблемный кейс: падение веб-сервиса на 4 часа из-за ручного выполнения команды ALTER TABLE orders DROP COLUMN customer_phone в разгар рабочего дня. Осознание необходимости версионирования.
2. Актуализация знаний и теоретический экскурс 15 мин
(00:05–00:20)
12 мин
(00:04–00:16)
Интерактивная презентация (слайды 2–11). Разбор инструментов Flyway и Liquibase. Структура мета-таблицы flyway_schema_history, вычисление чек-сумм. Накат (migrate) и откат (rollback). Паттерн Expand/Contract при Zero-Downtime развертывании.
3. Демонстрация эталонного рабочего процесса 10 мин
(00:20–00:30)
8 мин
(00:16–00:24)
Преподаватель на проекторе демонстрирует накат baseline V1__baseline.sql, затем накат миграции V2__add_field.sql, показывает изменение содержимого flyway_schema_history, моделирует конфликт контрольных сумм и выполняет сценарий безопасного отката через U2__undo.sql.
4. Самостоятельная практическая работа студентов 40 мин
(00:30–00:70)
30 мин
(00:24–00:54)
Работа обучающихся в интерактивном листе zanyatie.html по 4 предметным сценариям: разработка DDL прямой миграции, разработка Undo-скрипта отката, протоколирование метаданных в flyway_schema_history, проведение регрессионного теста совместимости старых запросов.
5. Контроль, разбор ошибок, рефлексия и ДЗ 10 мин
(00:70–00:80)
6 мин
(00:54–00:60)
Сравнительный анализ типичных багов (отсутствие дефолтных значений у NOT NULL колонок, нарушение целостности внешних ключей). Демонстрация слайда 15 с тематическим интернет-мемом. Выставление баллов по 4-балльной рубрике. Инструктаж по резервному ДЗ.

3. Фундаментальный технологический стек: Эволюция схемы БД

3.1. Системы миграций: Flyway vs Liquibase

Эволюция схемы БД в современных продуктовых командах подчиняется принципам CI/CD. Прямой доступ разработчиков к боевым серверам блокируется; все изменения DDL оформляются в виде версионированных скриптов, хранящихся в Git.

3.2. Соглашение об именовании миграций Flyway

V1__init_schema.sql       -- Версионированная миграция (Versioned): выполняется строго один раз
V2__add_barcode_col.sql   -- Следующая версия схемы (накат)
U2__add_barcode_col.sql   -- Undo-миграция (обратный откат для версии 2)
R__recreate_views.sql     -- Повторяемая миграция (Repeatable): выполняется при каждом изменении хэша файла
B3__cleanup_old_data.sql  -- Baseline-миграция (базовая точка отсчета)

3.3. Служебная таблица версий: flyway_schema_history

При первом запуске мигратора в базе данных создается техническая таблица, отслеживающая состояние каждого скрипта:

CREATE TABLE flyway_schema_history (
    installed_rank INT NOT NULL PRIMARY KEY,   -- Порядковый номер выполнения миграции
    version VARCHAR(50) NULL,                  -- Номер версии (NULL для Repeatable миграций)
    description VARCHAR(200) NOT NULL,         -- Описание из названия файла (замена _ на пробелы)
    type VARCHAR(20) NOT NULL,                 -- Тип: SQL, UNDO, BASELINE
    script VARCHAR(1000) NOT NULL,             -- Имя файла миграции (например, V2__add_barcode.sql)
    checksum INT NULL,                         -- CRC32 или SHA-256 контрольная сумма файла
    installed_by VARCHAR(100) NOT NULL,        -- Пользователь БД, выполнивший накат
    installed_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Дата и время наката
    execution_time INT NOT NULL,               -- Длительность исполнения в миллисекундах
    success BOOLEAN NOT NULL                   -- Флаг успешности (TRUE/FALSE)
);
Правило иммутабельности: Как только миграция применилась на production, файл V{N}__*.sql замораживается. Любое ручное исправление текста примененного файла изменит контрольную сумму (checksum), что приведет к аварийной остановке сборки с ошибкой ValidateFailedException: Migration checksum mismatch for migration version X.

3.4. Обеспечение Zero-Downtime Deployment: Паттерн Expand/Contract

При непрерывном развертывании (Blue-Green или Rolling Deployments) в течение определенного времени новая и старая версии клиентского приложения обращаются к одной и той же схеме БД одновременно. Если разработчик выполнит деструктивный DDL (удаление колонки, переименование, добавление NOT NULL без дефолта), старая версия упадет с ошибкой 500.

Для предотвращения простоев применяется паттерн расширения-сжатия (Expand / Contract):

  1. Фаза 1: Расширение (Expand): В базу добавляется новая колонка или таблица со смягченными ограничениями (NULLable, дефолтные значения). Старые колонки остаются нетронутыми.
  2. Фаза 2: Параллельная запись и бэкфилл (Write Both / Transition): Приложение версии N+1 начинает писать данные одновременно в старую и новую структуры. Фоновым скриптом (backfill) обновляются исторические данные.
  3. Фаза 3: Переключение чтения (Read New): Новая версия приложения переключает все SELECT-запросы на новую структуру. Старая колонка больше не читается.
  4. Фаза 4: Сжатие (Contract): После полного вывода из эксплуатации старой версии приложения накатывается миграция очистки (DROP COLUMN / DROP TABLE), удаляющая устаревшие артефакты.

4. Методология регрессионного тестирования после DDL-изменений

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

Вектор проверки Потенциальный риск дефекта Регрессионный тестовый сценарий
Обратная совместимость INSERT Новая колонка объявлена как NOT NULL без DEFAULT, из-за чего старый код вставки падает с ошибкой СУБД. Выполнение типового SQL-запроса INSERT из старой версии клиента (без упоминания новой колонки). Запись должна успешно создаваться.
Стабильность представлений и процедур Переименование или перенос полей ломает скомпилированные представления (VIEW), функции и триггеры. Вызов представлений и сохраненных процедур. Проверка состояния системного каталога на отсутствие инвалидированных объектов.
Производительность (Query Performance) Отсутствие или повреждение индексов после реструктуризации приводит к переходу СУБД в режим полного сканирования (Seq Scan / Table Scan). Анализ плана выполнения тяжелых запросов через EXPLAIN ANALYZE до и после миграции. Контроль времени отклика сводных отчетов.
Идемпотентность и обратимость Скрипт миграции падает при повторном запуске, либо откат оставляет в базе "фантомные" объекты. Тестовый накат: Migrate → Rollback → Migrate. Схема базы до и после цикла должна быть побайтово идентична.

5. Классификатор типовых студенческих ошибок и педагогические приемы

Ошибка №1: Добавление колонки NOT NULL без значения по умолчанию
Студенческий код: ALTER TABLE goods ADD COLUMN barcode VARCHAR(13) NOT NULL;
Последствия: Если таблица содержит хотя бы одну строку, СУБД отвергнет выполнение запроса (ошибка нарушения NOT NULL). Если таблица пуста, миграция пройдет, но любое старое приложение при вставке рухнет.
Педагогический прием: Попросить студента предварительно наполнить таблицу 10 тестовыми строками и попробовать запустить свой скрипт. Продемонстрировать необходимость конструкции DEFAULT 'DEFAULT_VALUE' либо добавления ограничения в два этапа.
Ошибка №2: Попытка ручного редактирования уже примененного файла миграции
Действие студента: Обнаружив опечатку в типе данных, студент исправляет файл V1__baseline.sql вместо создания миграции V2__fix_column.sql.
Последствия: Несоответствие хэша flyway_schema_history.checksum и падение сборки.
Педагогический прием: Показать студенту лог ошибки Flyway. Объяснить концепцию «журнала проводок»: в бухгалтерском учете ошибки не стирают ластиком, а проводят сторнирующую операцию.
Ошибка №3: Неполный Undo-скрипт отката (асимметричный rollback)
Студенческий код: В V3 создается таблица и внешний ключ, а в U3 удаляется только внешний ключ, таблица остается в схеме.
Последствия: База находится в «грязном» промежуточном состоянии, повторный накат невозможен (ошибка «Table already exists»).
Педагогический прием: Правило зеркала: каждое действие в прямом скрипте должно иметь строго обратную команду в обратном порядке (LIFO: Last In, First Out).

6. Критерии оценивания практической работы (4-балльная шкала)

Штрафные вычеты: синтаксическая ошибка DDL — -0.5 б.; отсутствие зеркальности в Undo-скрипте — -0.5 б.; пропуск регрессионного теста — -0.5 б.; отсутствие ответов на вопросы самопроверки — -0.5 б.