0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: postgresql, постгресс, столбец, изменение типа</p>
1
<p>Теги: postgresql, постгресс, столбец, изменение типа</p>
2
<p>В обычных случаях изменение типа столбца приведет к полной блокировке таблицы, причем блокировка будет продолжаться, пока все строки не обновятся в соответствии с новым типом. Но есть и исключения:</p>
2
<p>В обычных случаях изменение типа столбца приведет к полной блокировке таблицы, причем блокировка будет продолжаться, пока все строки не обновятся в соответствии с новым типом. Но есть и исключения:</p>
3
<ol><li>Приведение VARCHAR к типу TEXT (начиная с версии 9.1). Если говорить точнее, речь идет о ситуации, когда старый тип является бинарно совместимым с новым типом и для преобразования не нужны никакие фактические операции.</li>
3
<ol><li>Приведение VARCHAR к типу TEXT (начиная с версии 9.1). Если говорить точнее, речь идет о ситуации, когда старый тип является бинарно совместимым с новым типом и для преобразования не нужны никакие фактические операции.</li>
4
<li>Старый тип -- частный случай нового типа.</li>
4
<li>Старый тип -- частный случай нового типа.</li>
5
<li>В случае, когда увеличивается либо удаляется заданное ограничение на длину либо точность, к примеру:</li>
5
<li>В случае, когда увеличивается либо удаляется заданное ограничение на длину либо точность, к примеру:</li>
6
</ol><h2>На что важно обратить внимание?</h2>
6
</ol><h2>На что важно обратить внимание?</h2>
7
<p>Несмотря на то что, некоторые вышеупомянутые исключения были введены в версии 9.1, изменение типа индексируемого столбца в данной версии в любом случае приведет к переписыванию индекса. При этом, начиная с версии 9.2, индекс уже не переписывается (если содержимое таблицы не переписывалось). Но если вы захотите убедиться, что ваше изменение не инициирует перезапись, сделайте запрос к<strong>pg_class3</strong>и проверьте, что столбец<strong>relfilenode</strong>не подвергся изменениям.</p>
7
<p>Несмотря на то что, некоторые вышеупомянутые исключения были введены в версии 9.1, изменение типа индексируемого столбца в данной версии в любом случае приведет к переписыванию индекса. При этом, начиная с версии 9.2, индекс уже не переписывается (если содержимое таблицы не переписывалось). Но если вы захотите убедиться, что ваше изменение не инициирует перезапись, сделайте запрос к<strong>pg_class3</strong>и проверьте, что столбец<strong>relfilenode</strong>не подвергся изменениям.</p>
8
<p>Ну и последний совет: если потребуется поменять тип столбца, а вышеописанные исключения -- это не ваш случай, то можно сделать следующее:</p>
8
<p>Ну и последний совет: если потребуется поменять тип столбца, а вышеописанные исключения -- это не ваш случай, то можно сделать следующее:</p>
9
<ol><li>Добавьте новый столбец new_<column>.</li>
9
<ol><li>Добавьте новый столбец new_<column>.</li>
10
<li>Выполняйте запись одновременно в оба столбца (к примеру, посредством триггеров BEFORE INSERT/UPDATE).</li>
10
<li>Выполняйте запись одновременно в оба столбца (к примеру, посредством триггеров BEFORE INSERT/UPDATE).</li>
11
<li>Новый столбец заполните копиями значений из старого столбца.</li>
11
<li>Новый столбец заполните копиями значений из старого столбца.</li>
12
<li>Выполните переименование <column> в old_<column>, а new_<column>, в <column>, причем выполняйте это внутри единой транзакции и явного выражения LOCK .</li>
12
<li>Выполните переименование <column> в old_<column>, а new_<column>, в <column>, причем выполняйте это внутри единой транзакции и явного выражения LOCK .</li>
13
<li>Последним шагом удалите старый столбец.</li>
13
<li>Последним шагом удалите старый столбец.</li>
14
<p><em>По материалам статьи "<a>PostgreSQL at Scale: Database Schema Changes Without Downtime</a>".</em></p>
14
<p><em>По материалам статьи "<a>PostgreSQL at Scale: Database Schema Changes Without Downtime</a>".</em></p>
15
</ol>
15
</ol>