Бэкап базы данных - Cinema.backup.
Для тех слушателей, кто имеет старую версию SQL Server и не может развернуть Cinema_final, предлагается следующая последовательность действий:
- Сделать бекап своей базы данных Cinema
- Удалить свою базу данных Cinema
- Открыть приложенный скрипт cinema.sql
- В самом начале скрипта (строки 5 и 7) есть путь до папки SQL Server, который на вашем компьютере может немного отличаться (см. приложенный скрин). Замените путь на ваш правильный (скорее всего, надо будет только цифры 15 в названии папки исправить).

- Исполните скрипт.
- Обновите список баз данных, найдите Cinema и назначьте владельца в свойствах базы
Если не хотите удалять свою базу и имеется желание к самостоятельной работе, то из самого скрипта можете достать строки заполнения каждой из таблиц и далее заполнять таблицы в ручную.
Если при установке бэкапа базы данных "Cinema" с помощью SQL Server Management Studio она появилась в списке, компоненты отобразились в списке, но при попытке открыть dbo.Diagram открывается пустое окно, то для того, чтобы отображались данные в этом разделе нужно:
- Правой кнопкой мыши нажать на базе данных, выбрать: Свойства-раздел Файл-назначить владельца БД после восстановления.
- В диаграмме нажать правой кнопкой мыши, выбрать: Добавить таблицы-добавить все таблицы БД. Диаграмма автоматически построится.
Создание таблицы «Расписание»
Начнём с таблицы для расписания. Для хранения информации о сеансе необходимо знать: какой фильм, в каком формате, в каком зале и в какое время демонстрируется.
Создадим таблицу
«Расписание».
•
StartDate: поле типа
DateTime. Отвечает за дату и время начала сеанса.
•
ID Hall: поле типа
int, ссылка на зал.
•
ID Film: поле типа
int.
•
ID Format: поле типа
int.
Поля
ID Film и
ID Format вместе ссылаются на пересечение сущностей «Фильм» и «Формат». Комбинация полей
StartDate,
ID Hall,
ID Film и
ID Format образует
первичный ключ.
Протягиваем связи к таблицам «Холл» и «Фильм-Формат». Получаем рабочую схему для хранения сеансов.
Сотрудники и должности
Следующий шаг — работа с персоналом.
Создаём таблицу-справочник «
JobList» (список должностей).
•
ID: первичный ключ.
•
Job Title: название должности (
varchar).
•
Comment: необязательное поле для должностных обязанностей (
varchar(max)).
Далее создаём таблицу
«Person» (сотрудник):
•
Personal Number: табельный номер сотрудника, выполняет роль первичного ключа (
int).
•
FirstName,
SecondName: имя и фамилия (
varchar(30)).
•
BirthDate: дата рождения (
date).
•
Passport Number: номер паспорта (
int).
•
Job Title ID: внешний ключ к таблице
JobList.
Категориальное разделение (отношение «один к одному»)
Из всех сотрудников нас интересуют только кассиры, так как процесс продажи билетов обслуживают именно они. Для выделения специфических атрибутов кассира используем
категориальное разделение.
Это реализуется через связь
«один к одному».
Создаём таблицу
«Cashier» (кассир):
•
Personal Number: первичный ключ, который полностью совпадает с ключом родительской таблицы
Person.
•
Cash Register Number: номер кассы — атрибут, свойственный исключительно кассиру.
При полном совпадении первичных ключей связь «один к одному» определяется автоматически. В эту таблицу будут попадать только те сотрудники, которые являются кассирами.
Заказ (Order) и проблема суррогатного ключа
Моделируем факт покупки. Нам нужно знать, на какой сеанс куплен билет, когда совершена покупка и какой кассир обслужил заказ.
Создаём таблицу
«Order» (заказ). Первоначально в неё попадают поля из «Расписания»:
•
StartDate
•
ID Hall
•
ID Film
•
ID Format
и добавляются специфические поля:
•
Order Date: дата и время совершения заказа.
•
ID Person: идентификатор кассира.
В итоге получаем комбинацию из шести полей для первичного ключа. Это
очень сложный ключ. Чтобы упростить работу и дальнейшие ссылки, вводим
суррогатный ключ — дополнительное поле
ID, которое и станет первичным ключом. После этого настраиваем связи от таблицы
Order к таблицам «Расписание» и «Cashier».
Детализация заказа (Order Detail)
Заказ завершает таблица
«Order Detail», которая содержит информацию о конкретных купленных билетах.
•
ID Order: ссылается на суррогатный ключ таблицы «Order».
•
Item: номер позиции (билета) внутри заказа.
Поля
ID Order и
Item вместе образуют первичный ключ.
Чтобы указать конкретное место, добавляем поле
ID Place. Это внешний ключ к таблице «SitPlace». Протягиваем соответствующую связь.
В итоге мы спроектировали схему, охватывающую связи «многие ко многим», «один ко многим», «один к одному», а также различные типы ключей и категориальное разделение.
Управление базой данных: бекап и восстановление
По окончании проектирования важно уметь сохранять результат.
•
Создание резервной копии (Backup): В контекстном меню базы данных нужно выбрать
Tasks → Backup. В настройках важен режим
Full, который выгружает и схему, и данные целиком в один файл.
•
Восстановление (Restore): Если база данных удалена, через контекстное меню папки
Databases выбираем
Restore Database. Указываем источник — устройство, и находим наш файл бекапа. Система восстановит все таблицы и диаграммы.
На этом этапе проектирование схемы завершено. Однако логика работы приложения требует программной проверки согласованности данных, что будет рассмотрено в дальнейшем.
Краткие итоги
Последовательно выстроенная схема данных демонстрирует путь от абстрактной задачи к физической модели. Изначальная потребность фиксировать расписание сеансов привела к появлению таблицы, агрегирующей несколько измерений: время, место, продукт (фильм) и его атрибут (формат). Сложность связи «многие ко многим» между фильмами и форматами была корректно разрешена через промежуточную сущность, что позволило создать гибкое расписание.
Моделирование персонала выявило важный архитектурный принцип: не все атрибуты сущности одинаково релевантны для всех её экземпляров. Вместо создания избыточной таблицы с множеством необязательных полей было применено категориальное разделение. Использование отношения «один к одному» с наследованием первичного ключа позволило выделить кассиров, сохранив общую целостность данных о сотрудниках.
При переходе к процессу продажи проявилась проблема эскалации сложности естественных ключей. Композитный ключ из шести полей в таблице заказов делал бы связи громоздкими и неэффективными. Решение о введении суррогатного ключа является критически важным с практической точки зрения: оно упрощает разработку, повышает производительность и делает детализацию заказа тривиальной задачей.
Финальная стадия проектирования неразрывно связана с эксплуатацией. Демонстрация полного цикла резервного копирования и восстановления — это не просто техническая инструкция, а иллюстрация того, что созданная модель является самодостаточным и восстанавливаемым артефактом. Понимание того, что спроектированная схема — это лишь фундамент, закладывает основу для следующего этапа — программирования бизнес-логики и проверок ограничений, которые не всегда можно выразить декларативно.
1. Таблица расписания является связующим звеном между сущностями фильма, формата и зала.
2. Составные первичные ключи идеально подходят для моделирования пересечений «многие ко многим».
3. Категориальное разделение позволяет добавлять уникальные атрибуты подтипам сущностей без раздувания основной таблицы.
4. Связь «один к одному» автоматически образуется при полном совпадении первичных ключей в двух таблицах.
5. Длинные составные ключи (более 3–4 полей) усложняют разработку, поэтому для них вводят суррогатные идентификаторы.
6. Суррогатный ключ заменяет естественный составной ключ и становится единственным первичным ключом таблицы.
7. Таблица заказов фиксирует факт транзакции, не детализируя её содержимое.
8. Детализация заказа позволяет привязать каждый отдельный билет к конкретному месту в зале.
9. Ссылочная целостность гарантирует, что не будет продан билет на несуществующее место.
10. Полное резервное копирование (Full Backup) сохраняет и данные, и структуру базы.
11. Восстановление из бекапа требует предварительного разрыва активных соединений с базой данных.
12. Программные проверки (триггеры, процедуры) необходимы для контроля бизнес-правил, не заложенных в структуру таблиц.
1. Почему для хранения сеанса требуется ссылаться на сущность пересечения «Фильм-Формат», а не на фильм и формат по отдельности?
2. Каким образом обеспечивается связь «многие ко многим» на уровне физической модели базы данных?
3. В чем заключается принцип категориального разделения и для решения какой задачи он был применён?
4. Какое условие должно выполняться для первичных ключей, чтобы связь между таблицами автоматически стала «один к одному»?
5. Назовите основной недостаток использования длинного составного первичного ключа в таблице заказов.
6. Что такое суррогатный ключ и зачем он был введён в таблице Order?
7. Какую информацию хранит таблица «Order Detail» и как она связана с основным заказом?
8. Можно ли на основе данных таблицы Order узнать, кто из сотрудников оформил продажу?
9. Почему поле Cash Register Number было вынесено в отдельную таблицу, а не добавлено в общую таблицу Person?
10. В чем разница между полным (Full) и разностным (Differential) резервным копированием с точки зрения конечного файла?
11. Почему при попытке удалить базу данных может потребоваться установка галочки «Close existing connections»?