Реляционная таблица — это физическое воплощение математического отношения:
UNIQUE NOT NULL.
Три обязательных реляционных аксиомы первичного ключа:
NULL.По первичному ключу СУБД строит кластеризованный или уникальный B-Tree индекс.
INT, BIGINT, UUID.UNIQUE NOT NULL!Современные реляционные СУБД (PostgreSQL, MySQL, Oracle, MSSQL) поддерживают три основных стандарта:
GENERATED ALWAYS AS IDENTITY — стандарт SQL:2003 (предпочтительнее устаревшего SERIAL). Безопасен при явных вставках.BIGINT (BIGSERIAL) — 8 байт, обязателен для журналов транзакций, путевых листов, чеков, где счетчик быстро превысит 2.14 млрд.UUID (Universally Unique Identifier) — 16 байт, генерируется клиентом автономно. Незаменим в распределенных и оффлайн-приложениях.-- Стандарт SQL:2003 (PostgreSQL) id_avto INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, vin VARCHAR(17) NOT NULL UNIQUE
FLOAT, REAL, DOUBLE) для финансовых расчетов и цен!
Двоичное представление чисел с плавающей точкой (IEEE 754) дает ошибку округления: 0.1 + 0.2 = 0.30000000000000004.
NUMERIC(10,2) или DECIMAL(12,2) (точные десятичные дроби).INTEGER (до 2.14 млрд) или BIGINT.SMALLINT (до 32 767 — этажи, вместимость, стаж).VARCHAR(n) — строка переменной длины с ограничением (ФИО, email, название). Защищает от переполнения памяти.CHAR(n) — строка строго фиксированной длины (VIN ровно 17 символов, код валюты ISO ровно 3 символа).DATE и TIMESTAMP — календарные даты и временные метки. Хранить дату строкой VARCHAR(10) — грубая ошибка!BOOLEAN — логический флаг (TRUE, FALSE, NULL) для статусов активности и архивности.is_aktivnyy BOOLEAN NOT NULL DEFAULT TRUE, data_vyezda TIMESTAMP NOT NULL, vin CHAR(17) NOT NULL UNIQUE
Ограничения целостности выполняются на уровне ядра СУБД и не зависят от ошибок в коде веб-сервера или мобильного клиента:
NOT NULL: запрещает неопределенные значения. Обязателен для всех смысловых атрибутов.UNIQUE: предотвращает логическое дублирование записей (госномера, паспорта, логины).DEFAULT: значение по умолчанию при создании записи (например, CURRENT_TIMESTAMP или 0).Ограничение CHECK проверяет истинность логического выражения при каждой вставке или обновлении строки:
-- 1. Валидация жизненного цикла (перечисление)
CHECK (status IN ('доступен', 'занят', 'уборка', 'ремонт'))
-- 2. Темпоральная целостность (дата выезда позже заезда)
CHECK (data_vyezda > data_zaezda)
-- 3. Защита от отрицательных остатков и цен
CHECK (probeg_pri_vozvrashchenii >= probeg_pri_vyezde)
CHECK (cena_prodazhi >= cena_zakupki AND cena_zakupki >= 0)
Внешний ключ физически связывает таблицы при реализации отношений 1:M и 1:1:
INT ссылается на INT).NOT NULL.JOIN на внешние ключи обязательно создаются индексы.Промышленный стандарт по умолчанию. Блокирует удаление родительской записи, если есть дочерние строки. Защищает финансовые архивы, договоры и путевые листы.
Автоматически стирает дочерние записи. Опасно! Допустимо строго для неделимых подчиненных спецификаций (строки заказа при удалении черновика).
ON DELETE SET NULL зануляет ссылку при удалении родителя (например, уволен мастер-приемщик, но заказ сохранился).
CREATE TABLE putevye_listy (
id_putevogo_lista BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nomer_dokumenta VARCHAR(30) NOT NULL UNIQUE,
id_avto INT NOT NULL REFERENCES avtomobili(id_avto)
ON UPDATE CASCADE ON DELETE RESTRICT,
id_voditelya INT NOT NULL REFERENCES voditeli(id_voditelya)
ON UPDATE CASCADE ON DELETE RESTRICT,
probeg_pri_vyezde INT NOT NULL CHECK (probeg_pri_vyezde >= 0),
probeg_pri_vozvrashchenii INT,
CONSTRAINT chk_probeg CHECK (probeg_pri_vozvrashchenii >= probeg_pri_vyezde)
);
id SERIAL без ограничения уникальности на паспорт или VIN, что допускает дублирование реальных объектов.Robert'); DROP TABLE Students;--).