Добавить NOT NULL поле в большую таблицу
Вопрос
Как добавить обязательное поле region в таблицу на 50 млн строк PostgreSQL без долгой блокировки?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Сразу
ADD COLUMN region text NOT NULLбез дефолта: в PostgreSQL 11+ это мгновенно - Создать колонку с дефолтом
now()::text, а потом заменить значения пачками - Скопировать таблицу целиком в новую с колонкой и переключить имя таблиц
- Nullable-колонка, заполнение пачками,
CHECK ... NOT VALID,VALIDATE, NOT NULLправильный ответ
Разбор
Без дефолта NOT NULL на непустой таблице просто не применится. Изменчивый дефолт (как now()) заставляет переписать таблицу под тяжёлой блокировкой. Безопасный путь: nullable-колонка (мгновенно), заполнение пачками, ограничение CHECK (region IS NOT NULL) NOT VALID и его VALIDATE без блокировки записи, после этого SET NOT NULL в PostgreSQL 12+ использует проверенное ограничение и не сканирует таблицу. Если подходит константный дефолт, в PostgreSQL 11+ можно сразу ADD COLUMN ... DEFAULT 'x' NOT NULL, это тоже быстро.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Операции миграций Django
Следующий вопрос
Порядок шагов переименования колонки без простоя