Изменить столбец с INTEGER на BIGINT

В моей базе данных у меня есть несколько полей с типом INTEGER. Мне нужно изменить некоторые из них на BIGINT.

Итак, мой вопрос: могу ли я просто использовать следующую команду?

ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;

Правильно ли преобразованы содержащиеся данные? После преобразования этот столбец является «настоящим» столбцом BIGINT?

Я знаю, что это невозможно, если в этом столбце есть ограничения (Trigger, ForeingKey,...). Но если нет ограничений, возможно ли это сделать таким образом?

Или лучше преобразовать его с помощью Help-Column:

MyIntegerColumn -> MyIntegerColumnBac -> MyBigIntColumn

person Andreas    schedule 15.03.2017    source источник
comment
Если один или несколько из этих столбцов не имеют ограничений (таких как внешний ключ, индекс, значение по умолчанию, правило и т. д.), тогда ответ «Да», данные будут преобразованы правильно. (Это для Firebird 2.5. Для Firebird 3.0 я не знать).   -  person Val Marinov    schedule 15.03.2017
comment
Спасибо. Потому что я не хочу столкнуться с проблемами в будущем, которых я еще не знаю.   -  person Andreas    schedule 15.03.2017
comment
В соответствии с триггерами firebirdsql.org/refdocs/ и хранимые процедуры не препятствуют изменению типа столбцов, начиная с Firebird 2.5.   -  person René Hoffmann    schedule 15.03.2017


Ответы (1)


Когда вы выполняете

ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;

Firebird не будет преобразовывать существующие данные из INTEGER в BIGINT, вместо этого он создаст новую версию формата для таблицы.

При вставке новых строк или обновлении существующих строк значение будет сохранено как BIGINT, но при чтении Firebird на лету преобразует «старые» строки из INTEGER в BIGINT. Это происходит прозрачно для вас как пользователя. Это делается для предотвращения необходимости перезаписи всех существующих строк, что может быть дорогостоящим (операция ввода-вывода, сборка мусора старых версий строк и т. д.).

Поэтому, пожалуйста, используйте ALTER TABLE .. ALTER COLUMN, а не MyIntegerColumn -> MyIntegerColumnBac -> MyBigIntColumn. Есть некоторые исключения из этого правила, например (потенциально) преобразование набора символов с потерями лучше выполнять таким образом, чтобы предотвратить ошибки транслитерации на select, если символ не существует в новом наборе символов, или изменение столбца (var)char, чтобы он был короче (чего нельзя сделать с alter column).

Чтобы быть немного более конкретным: когда строка записывается в базу данных, она содержит версию формата (также известную как количество версий) этой строки. Версия формата указывает на описание строки (типы данных и т. д.), как Firebird должен читать эту строку. Таблица изменений создаст новую версию формата, и этот формат будет применяться при записи новых строк или обновлении существующих строк. При чтении старой строки Firebird применяет необходимое преобразование, чтобы представить эту строку в новом формате (например, добавление новых столбцов со значениями по умолчанию, преобразование типа данных столбца).

Эти версии формата также являются причиной ограничения количества таблиц изменений: если вы примените более 255 таблиц изменений к одной таблице, вы необходимо создать резервную копию и восстановить базу данных (версия формата — однобайтовая), прежде чем будут разрешены дальнейшие изменения к тому столу.

person Mark Rotteveel    schedule 15.03.2017
comment
Спасибо за это. Поэтому я собираюсь использовать ALTER TABLE MyTable ALTER COLUMN MyIntegerColumn TYPE BIGINT;. Я не знал о лимите в 255 альтер-операторов! Очень хорошо знать! Спасибо. Есть ли способ прочитать текущее количество версий таблицы? - person Andreas; 15.03.2017