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