Миграцию создания таблицы запускают повторно после ручного изменения уже существующей таблицы. Какой риск несёт условное создание объекта только по его имени?
Условное создание обычно проверяет только наличие объекта с заданным именем и не сравнивает его фактическую структуру с ожидаемой. Поэтому миграция может завершиться успешно, хотя столбцы, типы или ограничения существующей таблицы уже отличаются от требуемых.
Повторный запуск миграций нужен для устойчивого развертывания: скрипт могут выполнить повторно после сбоя, в новом окружении или при восстановлении базы. Условное создание уменьшает число ошибок из-за уже существующих объектов, но решает только задачу проверки наличия, а не синхронизации схемы.
Предположим, ожидаемая таблица должна содержать обязательный столбец и ограничение уникальности, а кто-то ранее создал таблицу с тем же именем без них. Условная команда создания не сообщит о несоответствии, и приложение начнёт работать с другой схемой, чем предполагает код.
Последствия могут проявиться не сразу: начнут приниматься некорректные данные, изменится план запросов или упадёт последующая миграция, которая ожидает отсутствующий столбец. Особенно опасно, что сам шаг условного создания выглядит успешно выполненным.
Наличие объекта и соответствие его определения — разные проверки. Условное создание отвечает на вопрос «существует ли объект?», но обычно не проверяет имена и типы столбцов, значения по умолчанию, ограничения, индексы и другие свойства схемы.
Поэтому условное создание подходит для безопасного первоначального развёртывания, когда существующий объект считается доверенным. Для управления версией схемы нужны отдельные проверяемые миграции: изменение таблицы, добавление ограничений после проверки данных или явная валидация метаданных.
Иллюстрация механизма:
Если таблица уже существует, поддерживающая такой синтаксис СУБД обычно не пересоздаёт её и не приводит к этому определению. Сам синтаксис и детали сообщений зависят от диалекта SQL, поэтому переносимость такого DDL нужно проверять отдельно.
Пересоздание таблицы под тем же именем также не является универсальным исправлением: оно может уничтожить данные, зависимости и права. Надёжнее хранить версию миграций, запрещать несанкционированные ручные изменения и выполнять структурные изменения отдельными шагами с проверками.
В тестовой базе таблица заказов была создана вручную: в ней отсутствовал столбец статуса и не было ограничения уникальности номера заказа. Миграция с условным созданием прошла без ошибки, но приложение позднее получило ошибку при обращении к статусу, а дубликаты номеров уже успели попасть в таблицу.
Вариант с удалением и повторным созданием был отвергнут: он мог привести к потере тестовых данных и зависимых объектов. Вариант с ручным сравнением каждого свойства оказался трудно поддерживаемым.
Выбрали последовательную миграцию: сначала проверили наличие дубликатов, затем добавили недостающий столбец, заполнили его, установили обязательность и добавили ограничение уникальности. В результате структура стала соответствовать ожидаемой, а существующие данные не были безусловно уничтожены.
Нет. Если объект уже существовал, команда может не выполнять тело определения вообще. Ограничения первичного и внешнего ключа, CHECK, UNIQUE, индексы и значения по умолчанию нужно проверять или создавать отдельными операциями.
Только в узком смысле: повторный запуск не вызывает ошибку из-за уже существующего объекта. Полная идемпотентность требует, чтобы после любого числа запусков схема приходила к одному и тому же состоянию. Простая проверка имени этого не обеспечивает.
Удаление уничтожает данные и сам объект, а вместе с ним могут исчезнуть зависимые объекты или измениться права доступа. Кроме того, поведение при зависимостях определяется правилами удаления и конкретной СУБД. Для рабочей базы безопаснее применять контролируемые ALTER-изменения, резервное копирование и отдельную проверку совместимости.