Как добавить столбец в SQL
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Базовый синтаксис
ALTER TABLE users ADD COLUMN phone VARCHAR(20);1. Несколько колонок сразу
Postgres / SQL Server
ALTER TABLE users
ADD COLUMN phone VARCHAR(20),
ADD COLUMN address TEXT,
ADD COLUMN created_at TIMESTAMP DEFAULT NOW();MySQL
ALTER TABLE users
ADD COLUMN phone VARCHAR(20),
ADD COLUMN address TEXT;2. С default значением
ALTER TABLE users
ADD COLUMN status VARCHAR(20) DEFAULT 'active';Для существующих строк проставится 'active'.
3. NOT NULL + default
ALTER TABLE users
ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT NOW();Важно: NOT NULL без DEFAULT на заполненную таблицу падает (куда deвать старые строки?). DEFAULT обязателен.
4. NOT NULL без default (двухшаговый процесс)
-- шаг 1: добавить nullable
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- шаг 2: заполнить
UPDATE users SET phone = 'N/A' WHERE phone IS NULL;
-- шаг 3: сделать NOT NULL
ALTER TABLE users ALTER COLUMN phone SET NOT NULL;5. Колонка по формуле (computed / generated)
Postgres 12+
ALTER TABLE users
ADD COLUMN full_name VARCHAR(200)
GENERATED ALWAYS AS (first_name || ' ' || last_name) STORED;MySQL
ALTER TABLE users
ADD COLUMN full_name VARCHAR(200)
AS (CONCAT(first_name, ' ', last_name)) STORED;Virtual vs stored:
- VIRTUAL — вычисляется при чтении
- STORED — сохраняется физически
6. Колонка с FK
ALTER TABLE orders
ADD COLUMN manager_id INT REFERENCES managers(id);Или отдельно:
ALTER TABLE orders ADD COLUMN manager_id INT;
ALTER TABLE orders
ADD CONSTRAINT fk_orders_manager
FOREIGN KEY (manager_id) REFERENCES managers(id);7. Колонка в определённом месте (MySQL)
MySQL позволяет управлять порядком:
-- в конец (default)
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- первой
ALTER TABLE users ADD COLUMN id INT FIRST;
-- после конкретной колонки
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;Postgres не поддерживает управление порядком — только в конец.
8. Большие таблицы (миллионы строк)
-- на миллиардах строк — ALTER TABLE блокирует таблицу
ALTER TABLE big_table ADD COLUMN new_col INT NOT NULL DEFAULT 0;В Postgres 11+ добавление колонки с DEFAULT — fast (без переписывания).
Для старых версий или MySQL — можно сделать shadow-таблицу и переименовать.
9. Добавить индекс на новую колонку
ALTER TABLE users ADD COLUMN country_code VARCHAR(2);
-- обновить значения
UPDATE users SET country_code = ...;
-- создать индекс
CREATE INDEX idx_users_country ON users(country_code);10. UNIQUE constraint при добавлении
ALTER TABLE users
ADD COLUMN employee_code VARCHAR(20) UNIQUE;Или отдельно:
ALTER TABLE users ADD COLUMN employee_code VARCHAR(20);
ALTER TABLE users ADD CONSTRAINT uq_emp_code UNIQUE (employee_code);Типичные типы данных
| Данные | Postgres | MySQL |
|---|---|---|
| Строка (короткая) | VARCHAR(n) | VARCHAR(n) |
| Строка (длинная) | TEXT | TEXT |
| Целое | INT, BIGINT | INT, BIGINT |
| Decimal | NUMERIC(p,s) | DECIMAL(p,s) |
| Float | REAL, DOUBLE PRECISION | FLOAT, DOUBLE |
| Boolean | BOOLEAN | TINYINT(1) |
| Date | DATE | DATE |
| Timestamp | TIMESTAMP, TIMESTAMPTZ | DATETIME, TIMESTAMP |
| JSON | JSONB | JSON |
| UUID | UUID | CHAR(36) или BINARY(16) |
Откатить (удалить колонку)
ALTER TABLE users DROP COLUMN phone;Осторожно: данные удалятся без возможности восстановления.
Частые ошибки
NOT NULL без DEFAULT на непустой таблице
-- ошибка
ALTER TABLE users ADD COLUMN required VARCHAR(10) NOT NULL;
-- правильно
ALTER TABLE users ADD COLUMN required VARCHAR(10) NOT NULL DEFAULT 'x';Забыть про миграции
В production изменения схемы делают через миграции (Alembic, Flyway, Liquibase), а не вручную.
Длинная ALTER TABLE на prod
Блокирует таблицу. Делайте в техническое окно или через NO REWRITE (Postgres 11+).
Не обновить запросы
После добавления колонки старые SELECT * могут получать неожиданные данные.
Связанные темы
FAQ
ALTER TABLE блокирует таблицу?
Зависит от СУБД и операции. Postgres 11+ с DEFAULT — нет. Старые версии — да.
Можно ли добавить колонку с NULL и сделать NOT NULL потом?
Да. Добавить → заполнить → ALTER COLUMN SET NOT NULL.
Где должна быть колонка — в конце или где-то?
В Postgres — только в конце. В MySQL — где угодно (FIRST, AFTER).
Удаление колонки мгновенное?
В Postgres — почти да (помечает invisible). В MySQL — может перестраивать таблицу (долго).
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.