Основы моделирования и базы данных

Физическая реализация. Часть 3

В материале демонстрируется логика проектирования реляционной базы данных кинотеатра — от статических объектов инфраструктуры до гибкой схемы продаж. Сначала создаются таблицы для залов, мест и их категорий, затем выстраивается многофакторное ценообразование с учётом типа дня, времени и формата. Далее моделируется контентная часть: фильмы, жанры, актёры и режиссёры. Ключевой акцент сделан на разрешении связей «многие ко многим» через ассоциативные таблицы и корректном назначении первичных и внешних ключей. Все сущности последовательно связываются в единую логическую схему, подготавливая основу для расписания и заказов.

Основные мысли

В результате изучения лекции слушатель будет способен:
1. Перечислить основные сущности базы данных кинотеатра и их ключевые атрибуты.
2. Объяснить назначение суррогатных и естественных первичных ключей в контексте модели.
3. Спроектировать таблицу для хранения мест в зале с учётом внешних ключей на зал и категорию.
4. Разработать структуру таблицы ценообразования, отражающую зависимость от типа дня, временного интервала, формата и категории места.
5. Создать ассоциативную таблицу для разрешения отношения «многие ко многим» между фильмами и жанрами.
6. Организовать связи актёров и режиссёров с фильмами через промежуточные таблицы.
7. Сформировать целостную логическую схему данных, объединив таблицы внешними ключами и устранив изолированные фрагменты.
8. Оценить необходимость вынесения повторяющихся атрибутов (тип дня, категория места) в отдельные справочники для обеспечения гибкости системы.
Показывать лекцию целиком
Краткое изложение
Создание таблицы мест и категорий

Следующая задача — создание таблицы Seat Place (место в зале). Для этого сначала нужен справочник категорий мест, поскольку категория будет внешним ключом.

Создаём таблицу Seat Category (категория места):
ID — целочисленный первичный ключ (primary key, PK) суррогатного типа.
Category Name — название категории, строка (varchar(20)), обязательно для заполнения.
Description — описание, строка (varchar(50)), необязательное.

Теперь создаём таблицу Seat Place:
ID — суррогатный первичный ключ (int).
ID Hall — внешний ключ к таблице зала (Hall), обязательно.
Row (ряд) — целое число, обязательно.
Place (место) — целое число, обязательно.
ID Category — внешний ключ (int) к таблице Seat Category, обязательно.

Поля ID Hall, Row и Place вместе логически идентифицируют конкретное место, но в качестве первичного ключа используется суррогатный ID. Строим связи: внешний ключ от Hall (ID Hall) и внешний ключ от Seat Category (ID Category).

Таблица ценообразования (Price)

Цена билета зависит от категории места и формата фильма. Создаём таблицу Price. Для удобства работы с типом дня (будний, выходной, праздничный) вынесем его в отдельный справочник.

Создаём справочник Day Type (тип дня):
ID — первичный ключ (int).
Type — название типа дня, строка (varchar(20)).

Теперь проектируем таблицу Price:
ID — суррогатный первичный ключ (int).
• ID Day Type — внешний ключ к Day Type (int), обязательно.
Time — время начала ценового периода внутри дня (time). Чтобы не указывать конец периода, храним только начало; окончание определяется началом следующей записи. Обязательное поле.
ID Format — внешний ключ к таблице формата (Format), обязательно.
ID Category — внешний ключ к Seat Category, обязательно.
Price Start — дата и время начала действия цены (datetime), обязательно. Позволяет учитывать изменение тарифов со временем (инфляция, новые прайс-листы).
Price End — дата и время окончания действия цены (datetime).
Price — денежная сумма (money), обязательно.

Связываем таблицу Price внешними ключами: к Day Type (ID Day Type), к Format (ID Format) и к Seat Category (ID Category). Таким образом, комбинация типа дня, интервала времени, формата и категории места определяет конкретную стоимость билета, а поля Price Start и Price End задают исторический период её актуальности.

Таблица фильмов (Film)

Переходим к контентной части. Создаём таблицу Film:
ID — первичный ключ (int), соответствующий уникальному лицензионному коду.
Year — год выпуска (date).
Name — название фильма (varchar(50)), обязательно.
Synopsis — краткое описание (text), необязательное.

Таблица жанров и связь с фильмами

Создаём справочник Genre (жанр):
ID — первичный ключ (int).
Name — название жанра (varchar(20)), обязательно.
Description — описание жанра (text), необязательное.

Фильм и жанр связаны отношением «многие ко многим» (many-to-many): один фильм может принадлежать к нескольким жанрам, и один жанр включает множество фильмов. Для разрешения такой связи необходима третья, ассоциативная таблица Film_Genre:
ID Film — внешний ключ к Film (int).
ID Genre — внешний ключ к Genre (int).
• Пара (ID Film, ID Genre) образует составной первичный ключ.

Проводим внешние ключи: от Film_Genre к Film и к Genre. Связь установлена.

Таблицы актёров и режиссёров

Аналогичное отношение многие ко многим существует между фильмами и актёрами, а также между фильмами и режиссёрами. Сначала создаём таблицы для самих персон.

Таблица Actor (актёр):
ID — первичный ключ (int).
First Name — имя (varchar(30)), обязательно.
Second Name — фамилия (varchar(30)), обязательно.
Birth Date — дата рождения (date), обязательно.

Таблица Director (режиссёр) с идентичной структурой:
ID — первичный ключ (int).
First Name, Second Name, Birth Date — те же типы и ограничения.

Далее создаём ассоциативные таблицы.

Film_Actor:
ID Film и ID Actor (оба int), вместе — первичный ключ.
• Внешние ключи к Film и Actor.

Film_Director:
ID Film и ID Director (оба int), вместе — первичный ключ.
• Внешние ключи к Film и Director.

Связь фильма с форматом

Фильм может показываться в разных форматах, а формат применим ко многим фильмам — снова отношение многие ко многим. Создаём таблицу Film_Format:
ID Film и ID Format (оба int) — составной первичный ключ.
• Внешние ключи к Film и Format.

Эта связь замыкает линию от форматов и объединяет две части модели: инфраструктурную (залы, форматы) и контентную (фильмы, персоны).

Дальнейшие шаги

Осталось создать таблицы Расписание (сеансы с привязкой к Film_Format, залу и времени) и Сотрудники. После этого будут построены финальные таблицы Order (заказ) и Order Detail (детали заказа), использующие всю спроектированную схему для продажи билетов.

Краткие итоги

Модель данных последовательно выстраивается от фундамента инфраструктуры кинотеатра к гибкой системе управления репертуаром и продажами. Исходной точкой становятся физические объекты — здания, залы и конкретные посадочные места с их категориями. Уже на этом этапе закладывается принцип суррогатных ключей, упрощающих связи и защищающих логическую целостность при изменениях бизнес-атрибутов.

Ценообразование проектируется не как статичный прайс-лист, а как многомерная матрица. В ней пересекаются четыре оси: тип дня (позволяет вводить разные тарифы для будней, выходных и праздников), временной интервал (внутридневное изменение цен), формат показа и категория места. При этом отказ от хранения времени окончания периода и переход к хранению только начала делает модель лаконичной, а добавление исторических дат действия цены превращает таблицу Price в полноценный журнал тарифных изменений, обеспечивая прозрачный аудит и возможность гибкого планирования акций.

Контентная часть моделируется по схожим принципам. Фильмы, жанры, актёры и режиссёры описываются минимально необходимыми атрибутами, а все неиерархические связи между ними разрешаются через ассоциативные таблицы с составными первичными ключами. Это позволяет легко добавлять новые жанры и персоны, связывать их с любым числом фильмов, а также, например, строить выборки по режиссёрам, работавшим в нескольких жанрах.

Завершающая сборка схемы через таблицу Film_Format критически важна: именно она соединяет инфраструктурную и контентную части, делая возможным формирование расписания сеансов, где конкретный фильм в конкретном формате назначается в конкретный зал на определённое время. Спроектированная модель не только покрывает текущие потребности, но и закладывает масштабируемую основу для добавления новых сущностей — сотрудников, программ лояльности, сложных правил бронирования — без нарушения уже существующей структуры.
Проектирование таблиц для залов, мест и цен

После создания таблицы зала (Hall) переходим к проектированию мест. Сначала нужен справочник Seat Category (категория места) с полями: суррогатный ID, название Category Name и описание Description. Затем создаём таблицу Seat Place (место) с суррогатным первичным ключом ID, внешним ключом ID Hall, полями Row (ряд) и Place (место), а также внешним ключом ID Category к Seat Category. Все поля обязательны. Связи устанавливаются с Hall и Seat Category.

Далее формируется ценообразование. Чтобы управлять типом дня (будний, выходной, праздничный), создаём справочник Day Type с ID и названием Type. Основная таблица Price включает:
• суррогатный ID;
• внешние ключи: ID Day Type, ID Format, ID Category (к Seat Category);
Time — время начала ценового периода внутри дня (только начало, так как конец определяется следующим началом);
Price Start и Price End — даты действия тарифа, позволяющие отслеживать историю изменения цен;
• денежное поле Price.

Все поля таблицы Price обязательны. Строятся внешние ключи к Day Type, Format и Seat Category. Так цена определяется пересечением дня, интервала, формата и категории места.

Фильмы, жанры и персоны

Таблица Film содержит суррогатный ID, год выпуска Year, название Name (обязательно) и краткое описание Synopsis (необязательно).

Таблица Genre (жанр): ID, Name (обязательно), Description (необязательно).

Фильмы и жанры связаны отношением многие ко многим, поэтому создаётся ассоциативная таблица Film_Genre с составным первичным ключом из пары ID Film и ID Genre. Оба поля — внешние ключи.

Аналогично проектируются актёры и режиссёры. Actor и Director имеют идентичную структуру: ID, First Name, Second Name, Birth Date (все поля обязательны). Для связи с фильмами создаются таблицы Film_Actor (поля ID Film и ID Actor) и Film_Director (ID Film и ID Director) с составными первичными ключами.

Связующая таблица и завершение модели

Фильмы и форматы также связаны многие ко многим — одна картина может демонстрироваться в нескольких форматах. Создаётся таблица Film_Format с парой ID Film и ID Format в качестве первичного ключа и соответствующими внешними ключами. Эта таблица соединяет инфраструктурную часть (залы, форматы) с контентной, позволяя строить расписание сеансов.

Завершающим этапом станет создание таблиц расписания и сотрудников, после чего появятся финальные Order (заказ) и Order Detail (детали заказа), замыкающие всю систему продажи билетов.

Выводы

1. Проектирование начинается с выделения ключевых сущностей инфраструктуры: зал, место и его категория.
2. Для таблицы мест используется суррогатный первичный ключ, что упрощает связи и модификацию данных.
3. Справочник категорий мест (Seat Category) вынесен в отдельную таблицу для гибкого управления.
4. Цена билета определяется пересечением четырёх параметров: типа дня, времени начала, формата и категории места.
5. Тип дня вынесен в самостоятельный справочник, а не задан текстом в таблице Price.
6. Хранение только времени начала периода в таблице Price позволяет не дублировать информацию о конце.
7. Поля Price Start и Price End превращают таблицу Price в исторический журнал тарифов.
8. Связь многие ко многим между фильмами и жанрами разрешается через ассоциативную таблицу Film_Genre.
9. Актёры и режиссёры хранятся в отдельных, но структурно идентичных таблицах с персональными данными.
10. Для связей фильмов с актёрами и режиссёрами созданы промежуточные таблицы Film_Actor и Film_Director.
11. Таблица Film_Format замыкает модель, связывая контент с форматами показа многие ко многим.
12. Созданная логическая схема подготавливает основу для построения расписания, заказов и работы с сотрудниками.

Вопросы для самопроверки

1. Из каких полей состоит первичный ключ таблицы Seat Place и почему выбран именно такой вариант?
2. Для чего понадобился справочник Seat Category отдельно от таблицы мест?
3. Как в таблице Price моделируется временной интервал действия цены внутри дня без указания времени окончания?
4. Каким образом таблица Price позволяет отслеживать историю изменения стоимости билетов?
5. Почему тип дня был вынесен в самостоятельную таблицу, а не оставлен текстовым полем в Price?
6. Какое отношение связывает фильмы и жанры и как оно реализовано?
7. Опишите структуру ассоциативной таблицы Film_Genre и её первичный ключ.
8. В чём сходство и различие таблиц Film_Actor и Film_Director?
9. Для чего предназначена таблица Film_Format и какие поля она содержит?
10. Какие поля таблицы Film обязательны, а какие могут оставаться пустыми?
11. Какие внешние ключи задействованы в таблице Price и с какими таблицами они связываются?
12. Какие сущности осталось спроектировать после создания таблиц Film, Actor и Film_Format?
Вернуться к учебному плану