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