pg_class, pg_attribute, pg_constraint).relfilenode).Создание надежной реляционной таблицы требует декларативного описания первичных ключей, типов данных и значений по умолчанию:
CREATE TABLE IF NOT EXISTS warehouses (
warehouse_id SERIAL PRIMARY KEY,
warehouse_code VARCHAR(20) NOT NULL UNIQUE,
warehouse_name VARCHAR(150) NOT NULL,
total_area_sqm NUMERIC(10, 2) NOT NULL CHECK (total_area_sqm > 0),
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
IF NOT EXISTS предотвращает ошибку при повторном запуске скрипта миграции.
Автоматически заполняют атрибут, если поле не передано в INSERT.
Явное именование ограничений критично для последующего сопровождения схемы.
pg_temp_*.CREATE TEMPORARY TABLE temp_shipment (
barcode VARCHAR(64) NOT NULL,
quantity INT CHECK (quantity > 0)
) ON COMMIT PRESERVE ROWS;
PRESERVE ROWS — сохраняются до конца сеанса.DROP — уничтожается при COMMIT транзакции.DELETE ROWS — очищается при завершении транзакции.В живой базе данных пересоздание таблицы недопустимо. Структура модифицируется «на лету»:
| Действие | Синтаксис SQL | Влияние на данные |
|---|---|---|
| ADD COLUMN | ALTER TABLE t ADD COLUMN zone VARCHAR(20) DEFAULT 'STD'; | Мгновенное добавление за $O(1)$ в PG 11+ |
| DROP COLUMN | ALTER TABLE t DROP COLUMN zone CASCADE; | Логическое скрытие, очистка при VACUUM |
| ALTER TYPE | ALTER TABLE t ALTER COLUMN cost TYPE NUMERIC(10,2) USING cost::NUMERIC; | Перезапись дисковых страниц, требует USING |
| RENAME | ALTER TABLE t RENAME COLUMN old_c TO new_c; | Обновление метаданных каталога за микросекунды |
| ADD CONSTRAINT | ALTER TABLE t ADD CONSTRAINT chk_v CHECK (cost > 0); | Валидация существующих кортежей |
| DROP CONSTRAINT | ALTER TABLE t DROP CONSTRAINT chk_v; | Снятие правила проверки целостности |
ALTER TABLE hotel_rooms
ALTER COLUMN price TYPE NUMERIC(10, 2);
Результат:ERROR: column "price" cannot be cast automatically to type numeric
СУБД блокирует опасные преобразования байтов без явного указания инженера!
ALTER TABLE hotel_rooms
ALTER COLUMN price TYPE NUMERIC(10, 2)
USING price::NUMERIC(10, 2);
Результат: Успешная конвертация каждой строки через заданное функциональное выражение или приведение типов (::).
Ограничения целостности гарантируют бизнес-инварианты на уровне реляционного ядра:
-- Проверочное ограничение CHECK
ALTER TABLE hotel_rooms
ADD CONSTRAINT chk_hotel_rooms_positive_price
CHECK (price_per_night > 0.00);
-- Внешний ключ FOREIGN KEY
ALTER TABLE bank_accounts
ADD CONSTRAINT fk_bank_accounts_client
FOREIGN KEY (client_id)
REFERENCES bank_clients(client_id)
ON DELETE RESTRICT;
-- Удаление ограничения уникальности
ALTER TABLE bank_accounts
DROP CONSTRAINT unq_account_number;
-- Удаление внешнего ключа
ALTER TABLE bank_accounts
DROP CONSTRAINT fk_bank_accounts_client;
Совет: всегда давайте ограничениям понятные системные имена, иначе их невозможно удалить без поиска в pg_constraint!
DROP TABLE bank_clients RESTRICT;
DROP TABLE transaction_audit_logs CASCADE;
| Критерий сравнения | TRUNCATE TABLE | DELETE FROM table |
|---|---|---|
| Подмножество языка | DDL (Data Definition Language) | DML (Data Manipulation Language) |
| Сложность выполнения | $O(1)$ — деаллокация файла кучи | $O(N)$ — построчное чтение и пометка |
| Объем журнала WAL | Минимальный (запись о новом relfilenode) | Колоссальный (запись каждого кортежа) |
| Построчные триггеры | Игнорируются (не вызываются) | Вызываются для каждой удаленной строки |
| Сброс автоинкремента | Поддерживает RESTART IDENTITY | Счетчик sequence никогда не сбрасывается |
| Условие WHERE | Не поддерживается (чистит всю таблицу) | Поддерживается построчный фильтр |
TRUNCATE TABLE student_attendance_log;
SERIAL сохраняет последнее значение.INSERT получит ID = 10001, а не 1.TRUNCATE TABLE student_attendance_log
RESTART IDENTITY;
Большинство операций ALTER TABLE и DROP TABLE захватывают самую жесткую блокировку в СУБД:
AccessExclusiveLock.SET lock_timeout = '2s';
ALTER TABLE orders ADD COLUMN ...;
Если блокировка не захвачена за 2 секунды, транзакция прерывается, сохраняя доступность базы для пользователей.
-- Фаза 1: мгновенное наложение (O(1))
ALTER TABLE orders
ADD CONSTRAINT chk_sum CHECK (sum > 0)
NOT VALID;
-- Фаза 2: фоновая проверка без блокировок
ALTER TABLE orders
VALIDATE CONSTRAINT chk_sum;
IF EXISTS / IF NOT EXISTS.BEGIN ... COMMIT (в PostgreSQL DDL транзакционен!).SET lock_timeout = '2s';.CONSTRAINT.CASCADE проверьте системные зависимости в pg_depend.TRUNCATE RESTART IDENTITY вместо DELETE.Создание таблицы Склады, добавление столбца Температурный_режим VARCHAR(20) DEFAULT 'STANDARD', переименование атрибута, безопасный DROP временной таблицы.
Конвертация типа столбца Стоимость с INTEGER на NUMERIC(10,2) с обязательным явным кастом USING, добавление ограничения CHECK (Стоимость > 0).
Добавление внешнего ключа в таблицу Счета с опцией ON DELETE RESTRICT, удаление устаревшего UNIQUE, безопасный DROP архивных логов с CASCADE.
Создание таблицы Дисциплины, наложение составного ограничения UNIQUE(Код, Семестр), высокоскоростная очистка посещаемости через TRUNCATE RESTART IDENTITY.
DROP TABLE обладает абсолютной разрушительной силой. Ошибки в проектировании схемы, отсутствие санитизации и неконтролируемые каскадные удаления способны мгновенно уничтожить инфраструктуру данных организации.