Как изменить тип столбца в PostgreSQL?

В обычных случаях изменение типа столбца приведет к полной блокировке таблицы, причем блокировка будет продолжаться, пока все строки не обновятся в соответствии с новым типом. Но есть и исключения:

  1. Приведение VARCHAR к типу TEXT (начиная с версии 9.1). Если говорить точнее, речь идет о ситуации, когда старый тип является бинарно совместимым с новым типом и для преобразования не нужны никакие фактические операции.
  2. Старый тип -- частный случай нового типа.
  3. В случае, когда увеличивается либо удаляется заданное ограничение на длину либо точность, к примеру:

На что важно обратить внимание?

Несмотря на то что, некоторые вышеупомянутые исключения были введены в версии 9.1, изменение типа индексируемого столбца в данной версии в любом случае приведет к переписыванию индекса. При этом, начиная с версии 9.2, индекс уже не переписывается (если содержимое таблицы не переписывалось). Но если вы захотите убедиться, что ваше изменение не инициирует перезапись, сделайте запрос к pg_class3 и проверьте, что столбец relfilenode не подвергся изменениям.

Ну и последний совет: если потребуется поменять тип столбца, а вышеописанные исключения -- это не ваш случай, то можно сделать следующее:

  1. Добавьте новый столбец new_<column>.
  2. Выполняйте запись одновременно в оба столбца (к примеру, посредством триггеров BEFORE INSERT/UPDATE).
  3. Новый столбец заполните копиями значений из старого столбца.
  4. Выполните переименование <column> в old_<column>, а new_<column>, в <column>, причем выполняйте это внутри единой транзакции и явного выражения LOCK .
  5. Последним шагом удалите старый столбец.
  6. По материалам статьи «PostgreSQL at Scale: Database Schema Changes Without Downtime».