Как изменить тип столбца в PostgreSQL?
В обычных случаях изменение типа столбца приведет к полной блокировке таблицы, причем блокировка будет продолжаться, пока все строки не обновятся в соответствии с новым типом. Но есть и исключения:
- Приведение VARCHAR к типу TEXT (начиная с версии 9.1). Если говорить точнее, речь идет о ситуации, когда старый тип является бинарно совместимым с новым типом и для преобразования не нужны никакие фактические операции.
- Старый тип -- частный случай нового типа.
- В случае, когда увеличивается либо удаляется заданное ограничение на длину либо точность, к примеру:
На что важно обратить внимание?
Несмотря на то что, некоторые вышеупомянутые исключения были введены в версии 9.1, изменение типа индексируемого столбца в данной версии в любом случае приведет к переписыванию индекса. При этом, начиная с версии 9.2, индекс уже не переписывается (если содержимое таблицы не переписывалось). Но если вы захотите убедиться, что ваше изменение не инициирует перезапись, сделайте запрос к pg_class3 и проверьте, что столбец relfilenode не подвергся изменениям.
Ну и последний совет: если потребуется поменять тип столбца, а вышеописанные исключения -- это не ваш случай, то можно сделать следующее:
- Добавьте новый столбец new_<column>.
- Выполняйте запись одновременно в оба столбца (к примеру, посредством триггеров BEFORE INSERT/UPDATE).
- Новый столбец заполните копиями значений из старого столбца.
- Выполните переименование <column> в old_<column>, а new_<column>, в <column>, причем выполняйте это внутри единой транзакции и явного выражения LOCK .
- Последним шагом удалите старый столбец.
По материалам статьи «PostgreSQL at Scale: Database Schema Changes Without Downtime».