Определим функциональные зависимости в прикладной области.
Рассмотрим атрибуты, характеризующие фильм.
Наименование фильма пока никаким атрибутом однозначно не определяется. Такую ситуацию мы будем условно обозначать следующим образом: 0→1.
Рассмотрим зависимость 1 → 7 («Наименование фильма»→«Метка носителя»). Мы вынуждены отбросить ее, т.к. возможна ситуация когда существует два фильма с одинаковым названием, но записанные на разные носители (пункт проката имеет два носителя идентичного содержания). Аналогичная ситуация возникает с зависимостями, где определяющая часть это «Наименование фильма», а определяемая – остальные атрибуты характеризующие фильм.
Вообще говоря, тройка 1,3,5 («Наименование фильма», «Режиссер фильма», «Год выхода фильма в прокат») однозначно определяет фильм (одни и те же режиссеры в один год редко снимают и картины, и их «ремейки»), и, следовательно, все атрибуты, касающиеся его. В дальнейшем эта тройка будет ключевыми атрибутами.
Значения атрибутов составных ключей многократно дублируются в записях соответствующих таблиц: например, не все режиссеры сняли только по одному достойному проката фильму. Поэтому в качестве ключевых атрибутов рекомендуется использовать как можно более короткие: номера, коды, шифры.
Большинство существующих СУБД поддерживают такой тип, как ID (счетчик) – он автоматически обслуживается СУБД. На физическом уровне основой индексных файлов являются именно ключевые поля отношений, поэтому крайне желательно использовать как можно короткие ключи фиксированной длины. ФИО и наименования организаций для этого очевидно не подходят.
Поэтому мы введем новый элемент данных: №18 «ИДЕНТИФИКАТОР ФИЛЬМА». По этим же соображениям введем атрибут №19 «ИДЕНТИФИКАТОР КЛИЕНТА».
Теперь функциональные зависимости примут следующий вид:
«Идентификатор фильма» → «Наименование фильма» (18→1)
«Идентификатор фильма» → «Продолжительность фильма» (18→2)
«Идентификатор фильма» → «Режиссер фильма» (18→3)
«Идентификатор фильма» → «Актеры, занятые в фильме» (18→4)
«Идентификатор фильма» → «Год выхода фильма в прокат» (18→5)
Ранее уже был определен атрибут «Идентификатор носителя». Рассмотрим теперь остальные атрибуты, касающиеся носителей.
«Идентификатор носителя» → «Метка носителя» (6→7)
«Идентификатор носителя» → «Рента за сутки» (6→10)
«Идентификатор носителя» → «Время добавления информации о носителе» (6→8)
«Идентификатор носителя» → «Идентификатор типа носителя» (6→17)
«Идентификатор носителя» → «Дата порчи-потери носителя» (6→11)
Обратим внимание на зависимость «Идентификатор носителя» → «Дата порчи-потери носителя» (6→11). Не все носители повреждены или украдены, а, следовательно, эта зависимость будет выполняться не для всех носителей, и в этих случаях атрибут из правой части будет принимать NULL значение. Использование NULL требует поддержки данного типа со стороны СУБД, а также, например, учета правил непривычной трехзначной логики при построении запросов.
Замечание1. Если предполагается, что неопределенные значения будут встречаться относительно редко (например, для документальных фильмов нельзя указать список актеров), то использование NULL-значений оправдано. В обратной ситуации, когда большинство записей будут содержать именно NULL-значение (именно дата порчи/потери носителя), целесообразно использовать понятие области определения функциональной зависимости.
Рассмотрим остальные зависимости.
«Идентификатор типа носителя» → «Тип носителя» (17→9)
Для этой зависимости и вводился атрибут «Идентификатор типа носителя».
«Идентификатор клиента» → «ФИО клиента» (19→14)
«Идентификатор клиента» → «Адрес электронной почты клиента» (19→15)
«Идентификатор клиента» → «Контактный телефон клиента» (19→16)
Объект выдача носителя клиенту характеризуется всеми своими атрибутами: носителем, клиентом, датой выдачи. По вышеописанным причинам необходимо ввести еще один атрибут для внутреннего пользования: №20 «ИДЕНТИФИКАТОР ВЫДАЧИ».
«Идентификатор выдачи» → «Идентификатор носителя» (20→6)
«Идентификатор выдачи» → «Идентификатор клиента» (20→19)
«Идентификатор выдачи» → «Дата выдачи носителя клиенту» (20→12)
«Идентификатор выдачи» → «Дата возврата носителя» (20→13)
Поскольку носитель каждый конкретный раз выдается только одному клиенту, это необходимо отразить в функциональных зависимостях:
«Идентификатор выдачи» → «ФИО Клиента», «Адрес электронной почты клиента», «Контактный телефон клиента»
Выше, при неформальном описании области отмечалась несколько нетривиальная связь фильма и носителя. Например, нельзя выделить зависимости «Идентификатор фильма» → «Идентификатор носителя» (18→6) и «Идентификатор носителя» → «Идентификатор фильма» (6→18): один фильм может располагаться на нескольких носителях, равно как и на одном носителе может быть несколько фильмов. Поэтому имеет место некоторое распределение фильмов по носителям.
Замечание 2. Распределение задается парой атрибутов «Идентификатор носителя», «Идентификатор фильма» (6, 18). Поскольку на один носитель два одинаковых фильма не пишут, эта пара также является составным ключом, и в дополнительном идентификаторе необходимости не возникает. Для фильмов, занимающих несколько носителей, необходимо хранить порядковый номер разбиения (например, номер части). Однако столь длинные картины все же редкость для кинопроката вообще, а, следовательно, для большинства пар фильм-носитель значение атрибута «Номер тома» будет равно одному и тому же, например, единице. Целесообразно следующее решение: ввести искусственный «Идентификатор распределения» (атрибут №21) и атрибут №22 «Номер тома».
Тогда получаем следующие зависимости:
«Идентификатор распределения» → «Идентификатор носителя» (21→6)
«Идентификатор распределения» → «Идентификатор фильма» (21→18)
«Идентификатор распределения» → «Номер тома» (21→22)