Функциональная зависимость X → Y означает, что значение атрибута X (детерминанта) однозначно определяет значение Y.
Неключевой атрибут зависит от всего составного ключа целиком, а не от его части.
(Order_ID, Item_ID) → Quantity
Зависимость через промежуточный неключевой детерминант: X → Y → Z.
Emp_ID → Pos_ID → Salary
Минимальный суперключ, уникально идентифицирующий каждый кортеж отношения.
PRIMARY KEY (emp_id)
X → A выполняется хотя бы одно из двух условий:
X — суперключ отношения;
A — первичный атрибут (входит в состав потенциального ключа).
Суть правила: «Каждый неключевой атрибут должен зависеть от ключа, от полного ключа и ни от чего, кроме ключа (so help me Codd)». Все промежуточные зависимости между неключевыми полями должны быть вынесены в отдельные отношения.
Если в таблице Employees(id, name, position, salary) оклад зависит от должности:
Оклад 80 000 руб. дублируется у всех 200 инженеров. Неоправданный расход диска и памяти кэша.
При изменении оклада нужно изменить 200 строк. Сбой посередине приведет к рассогласованию данных.
Нельзя внести новую должность «Архитектор» с окладом 150 000 руб., пока нет принятого сотрудника (PK is NULL).
При увольнении единственного инженера по ИБ из базы навсегда стирается сама должность и утвержденный оклад.
Y → Z (например: position_id → base_salary).positions(position_id PK, title, base_salary).base_salary из исходной таблицы сотрудников.position_id в таблице сотрудников как внешний ключ (FOREIGN KEY).X → A левая часть X обязана являться суперключом.
В BCNF полностью устранено послабление 3NF для первичных атрибутов. Любая зависимость, детерминант которой не является суперключом отношения, запрещена!
Допускает X → A, если A входит в потенциальный ключ. Защищает от транзитивности неключевых полей.
Исключений нет: детерминант X обязан быть суперключом. Строгое устранение всех аномалий ФЗ.
Это происходит исключительно при наличии составных перекрывающихся ключей.
Консультации(Студент, Предмет, Преподаватель)
(Студент, Предмет) → Преподаватель (у студента по предмету один преподаватель).
Преподаватель → Предмет (преподаватель ведет ровно один предмет).
{Студент, Предмет} и {Студент, Преподаватель}.Преподаватель → Предмет атрибут Предмет входит в ключ → в 3NF находится!Преподаватель — НЕ суперключ (не определяет студента) → BCNF нарушена!(Преподаватель, Предмет) и (Студент, Преподаватель).СУБД блокирует создание внешнего ключа, если родительская таблица еще не существует в базе данных.
Таблицы без внешних ключей:
departments manufacturers clients courses
Ссылаются на справочники:
positions medicines vehicles study_groups
Факты, транзакции, заказы:
employees batches repair_orders payments
CREATE TABLE positions (
position_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
title VARCHAR(100) NOT NULL UNIQUE,
base_salary NUMERIC(10, 2) NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT chk_salary_positive CHECK (base_salary >= 19242.00)
);
NUMERIC(10, 2): строго для цен и окладов (исключает погрешности FLOAT стандарта IEEE 754).VARCHAR(N): явный лимит длины строки вместо неограниченного TEXT.DATE / TIMESTAMP: встроенная валидация календарных дат ядром СУБД.PK: уникальность и запрет NULL для идентификации строк.
UNIQUE: защита от повторного ввода естественных ключей (ИНН, VIN, телефон).
CHECK: валидация бизнес-диапазонов (остаток >= 0, дата_сдачи > дата_выдачи).
NOT NULL: запрет неопределенных значений в критически важных полях.
ROLLBACK) на уровне ядра СУБД.
Опция ON DELETE во внешнем ключе определяет поведение СУБД при удалении родительской записи:
Пакет INSERT INTO должен доказать работоспособность структуры в 3 сценариях:
Не менее 5 связанных корректных строк, покрывающих ключевые сценарии бизнес-процесса.
Проверка граничных значений CHECK (минимальная цена, нулевой складской остаток).
Заведомо некорректные вставки для проверки срабатывания ограничений ядра СУБД.
id SERIAL без наложения UNIQUE на естественный бизнес-ключ (VIN, паспорт).Robert'); DROP TABLE Students;--).