
- •Часть 3 Проектирование базы данных
- •Глава 9. Функциональные зависимости.
- •9.1. Введение
- •9.2. Основные определения
- •9.3. Тривиальные и нетривиальные зависимости
- •9.4. Замыкание множества зависимостей
- •9.5. Замыкание множества атрибутов
- •9.6. Неприводимое множество зависимостей
- •9.7. Резюме
- •Глава 10 Дальнейшая нормализация:
- •1Нф, 2нф, 3нф, нфбк
- •10.1. Введение
- •10.2. Декомпозиция без потерь и функциональные зависимости
- •10.3. Первая, вторая и третья нормальные формы
- •10.4. Сохранение зависимости
- •10.5. Нормальная форма Бойса-Кодда
- •10.6. Резюме
- •Глава 12 Модель типа объект/отношение
- •12.1. Введение
- •12.2. Общий подход
- •12.3. Обзор модели объект/отношение
- •12.4. Диаграммы объект/отношение
- •12.5. Проектирование базы данных на основе модели типа объект/отношение
- •12.6. Краткий анализ
- •12.7. Резюме
12.5. Проектирование базы данных на основе модели типа объект/отношение
В некотором смысле диаграмма объект/отношение, построенная в соответствии с описанными выше правилами, является (очень абстрактным) макетом базы данных. Если попытаться в таком макете формально отобразить некоторую СУБД, то скоро станет ясно, что данная 0/0-диаграмма недостаточно точна и в ней не задано множество деталей (особенно тех, которые относятся к целостности). Для иллюстрации этого утверждения рассмотрим содержание макета, показанного на рис. 12.2, с точки зрения понятий реляционной базы данных.
Правильные объекты
На рис. 12.2 показаны перечисленные ниже правильные объекты:
DEPARTMENT
EMPLOYEE
SUPPLIER
PART
PROJECT
Каждый правильный тип объекта соответствует некоторому базовому отношению. Таким образом, рассматриваемая база данных будет содержать пять базовых отношений, например DEPT, EMP, S, Р и J, соответствующих этим пяти типам объектов. Более того, каждое из этих базовых отношений будет иметь первичный ключ — DEPT#, ЕМР#, S#, P# и J#, соответствующий "ключам", заданным в 0/0-диаграмме. Все эти факты будут задокументированы с помощью соответствующего набора утверждений на языке определения данных (data definition language — DDL) или, по крайней мере, с помощью некоторых предпосылок для такого набора утверждений. (Иначе говоря, для записи решений, принятых при проектировании базы данных, предполагается использование DDL-утверждений. Хотя это не единственный способ выполнения данной функции, но какой бы формальный метод при этом не использовался, он должен быть функционально эквивалентен этим утверждениям.) Ниже в качестве примера в кратком виде приводится такое утверждение для отношения DEPT:
CREATE BASE RELATION DEPT
( DEPT# DOMAIN ( DEPT# ) ... )
PRIMARY KEY ( DEPT# ) ;
Читателю в качестве упражнения предлагается сформулировать остальные утверждения.
Замечание. Домены и "множества значений" также должны быть задокументированы. Однако подробное описание этой темы здесь опускается, поскольку, как уже упоминалось выше, на данной 0/0-диаграмме множества значений не показаны.
Отношения типа многие-ко-многим
В рассматриваемом примере есть следующие отношения типа многие-ко-многим:
PROJ_WORK (между сотрудниками и проектами);
SUPP_PART (между поставщиками и товарами);
SUPP_PART_PROJ (между поставщиками, товарами и проектами);
PAR^STRUCTURE (между товарами и товарами).
Каждая такая зависимость соответствует некоторому базовому отношению. Таким образом, вводится еще четыре базовых отношения, соответствующих этим четырем зависимостям. Допустим, таким базовым отношением для SUPP_PART является SP (обычное отношение между поставщиками и товарами). Теперь можно отвлечься от описания первичного ключа для этого отношения и обратить внимание на внешние ключи, которые необходимы для идентификации участников данной зависимости.
CREATE BASE RELATION SP
( S# ... , P# ...,...)
FOREIGN KEY ( S# ) REFERENCES S FOREIGN KEY ( P# ) REFERENCES P ;
Ясно, что такое отношение должно включать два внешних ключа (S# и Р#), соответствующих двум участникам (поставщикам и товарам), и эти внешние ключи должны обращаться к соответствующим отношениям поставщиков S и Р. Более того, соответствующий набор правил для внешних ключей, т.е. правило обновления и правило удаления, должны быть заданы для каждого из этих внешних ключей (за более подробными сведениями по этой теме следует обращаться к главе 5). (Отметим, что здесь полностью игнорируется обработка пустой информации. В частности, здесь не рассматривается возможность использования во внешних ключах пустых значений, что подразумевает игнорирование и правила обработки пустой информации для внешних ключей, и опции NULLIFIES для правил обновления и удаления во внешних ключах.) В случае базового отношения SP следует задать приведенные ниже правила. (Эти правила, конечно, приведены в качестве иллюстрации; обратите, например, внимание на то, что они не связаны с помощью 0/0-диаграммы.)
CREATE BASE RELATION SP
( S# ... , P# ...,...)
FOREIGN KEY ( S# ) REFERENCES S
DELETE RESTRICTED
UPDATE CASCADES
FOREIGN KEY ( P# ) REFERENCES P
DELETE RESTRICTED
UPDATE CASCADES ;
Что можно сказать о первичном ключе этого отношения? Одним из способов его определения могла бы быть комбинация внешних ключей, которые идентифицируют участников (в случае базового отношения SP это S# и Р#), если эта комбинация имеет уникальное значение для каждого экземпляра этого отношения (обычно так и бывает, хотя могут быть и обратные случаи), если в ней содержится условие NULLS NOT ALLOWED, т.е. null-значения недопустимы (обычно так и бывает, хотя могут быть и обратные случаи), и если разработчик базы данных не возражает против использования составных первичных ключей (на практике это в равной степени возможно и невозможно). (Второе из перечисленных условий требуется для удовлетворения правила целостности объектов базового отношения SP. Как уже упоминалось выше, в рассматриваемом примере в любом случае все внешние ключи будут иметь статус NULLS NOT ALLOWED, так что этот вопрос не имеет никакого отношения к данному обсуждению.) В качестве альтернативного варианта первичного ключа можно использовать новый несоставной атрибут "номер поставки". В рассматриваемом примере будет использован первый из двух описанных выше вариантов. Таким образом, в утверждение CREATE BASE RELATION для SP следует добавить директиву
PRIMARY KEY ( S#, P# )
Читателю предлагается самостоятельно рассмотреть в качестве упражнения отношения PROJ_WORK, PART_STRUCTURE и SUPP_PART_PROJ.
Отношения типа многие-к-одному
В рассматриваемом примере заданы три отношения типа многие-к-одному:
PROJ_MANAGER (между проектами и менеджерами);
DEPT_EMP (между сотрудниками и отделами);
EMP_DEP (между подчиненными и сотрудниками).
Только последнее отношение содержит слабый тип объекта (DEPENDENT), а два других — правильные типы объектов. Отношение со слабым типом объекта рассматривается несколько позже, а сейчас рассмотрим какое-либо из двух других, например DEPT_EMP. В таком примере не нужно вводить никаких новых отношений. Вместо этого достаточно просто ввести приведенный ниже внешний ключ со стороны "многие" (ЕМР), который обращается к отношению со стороны "один" (DEPT):
CREATE BASE RELATION EMP
( EMP# …, DEPT# …, … )
PRIMARY KEY ( EMP# )
FOREIGN KEY ( DEPT#) REFERENCES DEPT
DELETE…
UPDATE…;
В данном случае возможности для правил внешних ключей точно такие же, что и для внешнего ключа, который представляет участника отношения типа многие-ко-многим в общем случае. Здесь вновь следует отметить, что они не показаны на данной 0/0-диаграмме.
Замечание. В рассматриваемом примере предполагается, что отношения типа один-к-одному (которые в общем случае не очень распространены на практике) следует рассматривать точно так же, как и отношения многие-к-одному. Подробное описание особенностей использования отношений типа один-к-одному приводится в [12.9].
Слабые объекты
Связь слабого типа объекта с сильным, от которого он зависит, конечно, является связью типа многие-к-одному, как это уже отмечалось. Однако внешние ключи для этой связи должны выглядеть так, как показано ниже. (Кроме того, если задано правило для обработки пустой информации, оно должно выглядеть как NULLS NOT ALLOWED.)
DELETE CASCADES
UPDATE CASCADES
Взятые вместе, эти правила выражают необходимую зависимость существования, которая иллюстрируется следующим примером:
CREATE BASE RELATION DEPENDENT
( EMP# ... )
FOREIGN KEY ( EMP# ) REFERENCES EMP
DELETE CASCADES
UPDATE CASCADES ;
Что является первичным ключом для данного отношения? Как и в случае с отношением многие-ко-многим, здесь также можно осуществить выбор. Одним из вариантов является комбинация внешнего ключа и "ключа" слабого объекта из 0/0-диаграммы, если (опять) разработчик базы данных не имеет возражений против использования составных первичных ключей. Альтернативным вариантом первичного ключа является введение нового несоставного атрибута. В рассматриваемом примере опять применяется первый из двух приведенных выше вариантов с использованием следующей директивы (в которой DEP_NAME является именем подчиненного данного сотрудника) в утверждении CREATE BASE RELATION для базового отношения DEPENDENT:
PRIMARY KEY ( ЕМР#, DEP_NAME )
Свойства
Каждому свойству, показанному на 0/0-диаграмме, соответствует атрибут данного отношения, за исключением случая многозначного свойства, когда для него требуется создать новое отношение в соответствии с принципами нормализации. Домены для множеств значений создаются простым и очевидным способом (хотя, конечно, сам выбор множеств значений может оказаться не совсем простой задачей), а потому подробности здесь опущены.
Супертипы и подтипы
Поскольку на рис. 12.2 не содержится никаких супертипов и подтипов, далее речь пойдет о примере, представленном на рис. 12.3. Каждому типу объекта на этом рисунке соответствует некоторое базовое отношение с атрибутами для свойств, которые применяются на заданной позиции внутри иерархии типов (а значит, наследуются на всех подчиненных позициях, но не на тех, которым они подчиняются). Рассмотрим, например, базовые отношения, ЕМР и PGMR, соответствующие типам объектов EMPLOYEE и PROGRAMMER:
CREATE BASE RELATION ЕМР
( EMP# . . . , DEPT# ... , SALARY ... , ... )
PRIMARY KEY ( EMP# ) ;
CREATE BASE RELATION PGMR
( EMP# ... , LANG ...,...)
PRIMARY KEY ( EMP# )
FOREIGN KEY (EMP#) REFERENCES ЕМР . . . ;
Здесь атрибут LANG представляет свойство "язык программирования, которым программист владеет в наибольшей мере", присущее только тем сотрудникам, которые являются программистами. Обратите внимание, что отношения ЕМР и PGMR обладают одинаковыми первичными ключами (ЕМР#); более того, первичный ключ для подчиненного типа (PGMR) также служит внешним ключом, который обращается к первичному ключу супертипа (ЕМР). Читателю предлагается самостоятельно выбрать соответствующий набор правил для этого внешнего ключа, а также разобраться с другими типами объектов, показанными на рис. 12.3 (APPLICATION_PROGRAMMER и SYSTEM_PROGRAMMER).