Дисциплина: ОП.08 Основы проектирования баз данных (СПО 09.02.07).
Тема: Тема 2. Взаимосвязи в моделях и реляционный подход к построению моделей — Практическое занятие №3: сущности и связи (§2.2 с.7 программы).
Фундаментальное руководство по трансляции концептуальных ER-моделей в реляционные структуры таблиц, декомпозиции связей многие-ко-многим и настройке ссылочной целостности.
Проектирование базы данных состоит из последовательных уровней абстракции: концептуального (модель «сущность-связь», ERD), логического (реляционная схема отношений) и физического (конкретные таблицы в СУБД с индексами и типами хранения).
Сложность перехода заключается в том, что в реляционной теории Эдгара Кодда отсутствуют прямые физические конструкции для представления связей. Все связи моделируются исключительно совпадением значений первичных (PRIMARY KEY) и внешних (FOREIGN KEY) ключей.
Трансляция концептуальной схемы выполняется строго по пятишаговому алгоритму, гарантирующему нормализацию и целостность:
INT или BIGINT. Для естественных кодов накладываются ограничения уникальности UNIQUE NOT NULL.FOREIGN KEY UNIQUE. Если сущности разделяют одинаковый жизненный цикл (Покупатель — Корзина), первичный ключ корзины одновременно объявляется внешним ключом к покупателю.id_rezhissera добавляется в таблицу filmy.INT ссылается строго на INT). Для справочников устанавливается ON DELETE RESTRICT, для зависимых строк спецификаций — ON DELETE CASCADE.Рассмотрим детальные промышленные примеры реализации ассоциативных таблиц для различных предметных областей.
Связь многие-ко-многим: актер снимается во множестве фильмов, в фильме занято множество актеров. Атрибуты связи: роль (персонаж), признак главной роли, индивидуальный гонорар.
-- Таблица сильной сущности «Фильмы»
CREATE TABLE filmy (
id_filma INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nazvanie VARCHAR(150) NOT NULL,
god_vypuska SMALLINT NOT NULL CHECK (god_vypuska >= 1895),
id_rezhissera INT NOT NULL REFERENCES rezhissery(id_rezhissera)
ON UPDATE CASCADE ON DELETE RESTRICT
);
-- Таблица сильной сущности «Актеры»
CREATE TABLE aktery (
id_aktera INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
familiya VARCHAR(60) NOT NULL,
imya VARCHAR(60) NOT NULL,
data_rozhdeniya DATE NOT NULL
);
-- Промежуточная связующая таблица «Фильм_Актер»
CREATE TABLE film_akter (
id_filma INT NOT NULL REFERENCES filmy(id_filma)
ON UPDATE CASCADE ON DELETE CASCADE,
id_aktera INT NOT NULL REFERENCES aktery(id_aktera)
ON UPDATE CASCADE ON DELETE RESTRICT,
rol_personazh VARCHAR(120) NOT NULL,
is_glavnaya BOOLEAN NOT NULL DEFAULT FALSE,
gonorar NUMERIC(12,2) CHECK (gonorar >= 0),
PRIMARY KEY (id_filma, id_aktera, rol_personazh)
);
rol_personazh. Это позволяет одному и тому же актеру исполнять несколько ролей в одном фильме (например, близнецов или эпизодических персонажей).
Один заказ включает несколько блюд, блюдо входит во множество заказов. Атрибуты связи: количество порций, цена на момент заказа.
CREATE TABLE poziciya_zakaza (
id_zakaza BIGINT NOT NULL REFERENCES zakazy(id_zakaza)
ON UPDATE CASCADE ON DELETE CASCADE,
id_blyuda INT NOT NULL REFERENCES blyuda(id_blyuda)
ON UPDATE CASCADE ON DELETE RESTRICT,
kolichestvo SMALLINT NOT NULL DEFAULT 1 CHECK (kolichestvo > 0),
cena_na_moment_zakaza NUMERIC(8,2) NOT NULL CHECK (cena_na_moment_zakaza > 0),
PRIMARY KEY (id_zakaza, id_blyuda)
);
cena_na_moment_zakaza фиксирует историческую стоимость транзакции. Если цена в меню blyuda изменится, закрытый заказ сохранит исходную стоимость.
Внешний ключ (FOREIGN KEY) гарантирует, что значение в дочерней таблице обязано соответствовать существующему первичному ключу в родительской таблице, либо быть равным NULL.
| Опция действия | Поведение при DELETE родительской строки | Типичные кейсы применения |
|---|---|---|
RESTRICT / NO ACTION |
Транзакция прерывается с ошибкой, если на родительскую строку ссылается хотя бы одна дочерняя запись. | Справочники сотрудников, авторов, категорий товаров, аккаунты клиентов с историей заказов. |
CASCADE |
СУБД автоматически физически удаляет все зависимые дочерние записи. | Позиции в удаляемом заказе, строки корзины покупок, связующие записи кастинга при удалении фильма. |
SET NULL |
СУБД присваивает внешнему ключу значение NULL. Дочерняя колонка не должна иметь NOT NULL. |
Необязательные ссылки: промокод на скидку, куратор студенческой группы, менеджер сделки. |
ON DELETE CASCADE на внешний ключ связи «Заказ -> Клиент»? К каким последствиям для финансовой отчетности это приведет?