Учебное пособие Допущено Министерством образования Российской Федерации в качестве учебного пособия для студентов высших учебных заведений, обучающихся по специальности
Вид материала | Учебное пособие |
- В. В. Крупица Личность Коллектив Стиль отношений (социально-психологический аспект), 4876.34kb.
- Учебное пособие допущен о министерством образования и науки Российской Федерации, 3988.52kb.
- Учебное пособие Выпуск второй, 4617.34kb.
- М. В. Ломоносова Хрестоматия по истории государства и права зарубежных стран, 11295.75kb.
- В. И. Королева Москва Магистр 2007 Допущено Министерством образования Российской Федерации, 4142.55kb.
- Учебное пособие для вузов, 3736.61kb.
- Учебное пособие для вузов, 7834.87kb.
- И. М. Синяева, В. М. Маслова, В. В. Синяев сфера, 5230.77kb.
- Д. В. Андреев Программирование микроконтроллеров mcs-51, 2064.3kb.
- Т. В. Корнилова экспериментальная психология теория и методы допущено Министерством, 5682.25kb.
Определение 2. Неключевой атрибут
Неключевым атрибутом называется любой атрибут отношения, не входящий в состав первичного ключа
Определение 3. Полная функциональная зависимость
Функциональная зависимость называется полной, если неключевой атрибут зависит от всего составного ключа и не зависит от его частей.
Определение 4. Транзитивная функциональная зависимость
Если атрибут B функционально зависит от атрибута A (AB), а атрибут C функционально зависит от атрибута B (BC), но обратная зависимость отсутствует, то говорят, что атрибут С зависит от А транзитивно.
Определение 5. Взаимно независимые атрибуты
Два или более атрибута взаимно независимы, если ни один из этих атрибутов не является функционально зависимым от других.
Определение 6. Отношение находится в первой нормальной форме (1NF), если значения его атрибутов атомарны. Исходное отношение строится таким образом, чтобы оно было в 1NF.
Определение 7. Отношение находится во второй нормальной форме (2NF), если выполняются ограничения первой нормальной формы и каждый неключевой атрибут функционально полно зависит от всего первичного ключа.
Определение 8. Отношение находится в третьей нормальной форме (3NF), если выполняются ограничения второй нормальной формы и все неключевые атрибуты взаимно независимы и полностью зависят от первичного ключа (т. е. в отношении отсутствуют транзитивные зависимости неключевых атрибутов от первичного ключа).
Проектирование базы данных рассмотрим на следующем примере. Пусть имеются сведения о поставках некоторой фирмой материалов. Сформируем исходное отношение Поставки (табл. 11).
Таблица 11
Таблица Поставки
Код_зака-за | Код_ма-териала | Код_клиен-та | Город клиента | Количество | Дата поставки | ||
1 | 2 | 3 | 4 | 5 | 6 | ||
110 | 21 | BN | Омск | 300 | 25.07.02 | ||
110 | 30 | BN | Омск | 200 | 25.07.02 | ||
120 | 13 | BR | Москва | 160 | 12.08.02 | ||
120 | 15 | BR | Москва | 150 | 12.08.02 | ||
| |||||||
Окончание табл. 11 | |||||||
1 | 2 | 3 | 4 | 5 | 6 | ||
120 | 16 | BR | Москва | 80 | 12.08.02 | ||
120 | 18 | BR | Москва | 250 | 12.08.02 | ||
130 | 20 | BR | Москва | 120 | 14.08.02 | ||
130 | 55 | BR | Москва | 200 | 14.08.02 | ||
130 | 71 | BR | Москва | 300 | 14.08.02 | ||
140 | 2 | BS | Тюмень | 300 | 26.08.02 | ||
140 | 62 | BS | Тюмень | 90 | 26.08.02 | ||
150 | 31 | BN | Омск | 60 | 4.09.02 | ||
150 | 70 | BN | Омск | 20 | 4.09.02 | ||
160 | 30 | AN | Улан-Удэ | 50 | 18.09.02 | ||
160 | 69 | AN | Улан-Удэ | 10 | 18.09.02 |
В качестве первичного ключа выберем составной ключ Код_заказа-Код_материала, однозначно определяющий каждый кортеж отношения. Данное отношение находится в 1NF, т. к. все значения столбцов являются атомарными. Эта таблица содержит избыточные данные. например, одни и те же сведения о клиенте повторяются в записи о каждом заказанном материале. Результатом избыточности являются следующие аномалии:
- адрес клиента можно ввести в базу данных тогда, когда он заказал хотя бы одну ткань;
- при удалении записи о заказанной ткани одновременно удаляются сведения о заказе и клиенте, его разместившем;
- при смене адреса клиента, необходимо обновлять все записи и заказанных им материалах.
Напомним, что отношение находится во второй нормальной форме, если оно находится в первой нормальной форме и его неключевые атрибуты полностью зависят от всего первичного ключа. В таблице Поставки неключевые атрибуты Код_клиента, Город_клиента, Дата поставки зависят от атрибута Код_заказа, являющегося частью составного ключа. Поэтому отношение Поставки не соответствует второй нормальной форме.
Для того чтобы перейти от первой ко второй нормальной форме, необходимо выполнить следующие шаги:
- определить, на какие части можно разбить первичный ключ, так, чтобы некоторые из неключевых атрибутов функционально полно зависели от одной из этих частей;
- создать новое отношение для каждой такой части ключа и группы зависящих от нее атрибутов и переместить их в это отношение (т. е. построить проекции на части составного первичного ключа и атрибуты, зависящие от этих частей). Часть бывшего ключа станет при этом первичным ключом нового отношения;
- удалить из исходной таблицы атрибуты, перемещенные в другие отношения, кроме тех из них, которые станут внешними ключами (построить проекцию без атрибутов, находящихся в частичной функциональной зависимости от первичного ключа).
Для приведения исходной таблицы ко второй нормальной форме поля Код_заказа, Код_клиента, Город_клиента, Дата_поставки перемещаются в новую таблицу Поставки1, при этом Код_заказа – первичный ключ новой таблицы.
Вторая таблица Заказы будет содержать составной первичный ключ Код_заказа-Код_материала и поле Количество.
В результате новые таблицы будут выглядеть следующим образом (табл. 12-13):
Таблица 12 Таблица 13
Поставки1 Заказы
Код_за-каза | Код_кли-ента | Город клиента | Дата поставки | | Код_за-каза | Код_ма-териала | Коли-чество |
110 | BN | Омск | 25.07. 02 | | 110 | 21 | 300 |
120 | BR | Москва | 12.08. 02 | | 110 | 30 | 200 |
130 | BR | Москва | 14.08. 02 | | 120 | 13 | 160 |
140 | BS | Тюмень | 26.08. 02 | | 120 | 15 | 150 |
150 | BN | Омск | 4.09.02 | | 120 | 16 | 80 |
160 | AN | Улан-Удэ | 18.09. 02 | | 120 | 18 | 250 |
| | | | | 130 | 20 | 120 |
| | | | | 130 | 55 | 200 |
| | | | | 130 | 71 | 300 |
| | | | | 140 | 2 | 300 |
| | | | | 140 | 62 | 90 |
| | | | | 150 | 31 | 60 |
| | | | | 150 | 70 | 20 |
| | | | | 160 | 69 | 10 |
| | | | | 160 | 30 | 50 |
Проанализируем полученные таблицы. В таблице Заказы не наблюдается явная избыточность данных. Однако для таблицы Поставки1 можно указать следующие аномалии:
- адрес конкретного клиента может содержаться в базе только тогда, когда есть заказы;
- удаление сведений о заказе в таблице Поставки1 приведет к удалению сведений о клиентах;
- при изменении адреса заказчика придется обновить все кортежи в таблице Поставки1.
Устранить эти аномалии позволяет третья нормальная форма. Считается, что таблица соответствует третьей нормальной форме, если она находится во второй нормальной форме и ее неключевые атрибуты взаимно независимы и зависят только от первичного ключа. В отношении Поставки1 существует транзитивная зависимость между неключевыми атрибутами Город_клиента и Код_клиента (Код_клиента Город_клиента).
Для перехода от второй нормальной формы к третьей необходимо исключить транзитивные зависимости. Для этого требуется выполнить следующие шаги:
- определить все атрибуты (или группы атрибутов), от которых зависят другие атрибуты (выявить транзитивные зависимости);
- создать новое отношение для каждого такого атрибута и для группы зависящих от него атрибутов и переместить их в это отношение (т. е. построить проекцию отношения на атрибуты, являющиеся причиной транзитивной зависимости). Атрибут, от которого зависят все остальные перемещенные атрибуты, станет при этом первичным ключом нового отношения;
- удалить перемещенные атрибуты из исходного отношения, оставив лишь те, которые станут внешними ключами .
Для приведения таблицы Поставки1 к третьей нормальной форме создадим новую таблицу Клиенты (табл. 14) и переместим в нее атрибуты Код_клиента и Город_клиента. Атрибут Город_клиента из таблицы Поставки1 удалим, а атрибут Код_клиента оставим в качестве внешнего ключа (табл. 16). Таблицу Заказы оставим без изменения (табл. 15).
Таблица 14 Таблица 15
Клиенты Заказы
Код_кли-ента | Город клиента | | | Код_за-каза | Код_ма-териала | Количество |
BN | Омск | | | 1 | 2 | 3 |
BR | Москва | | | 110 | 21 | 300 |
BS | Тюмень | | | 110 | 30 | 200 |
AN | Улан-Удэ | | | 120 | 13 | 160 |
| | | | 120 | 15 | 150 |
| | | | 120 | 16 | 80 |
Окончание табл. 15 | ||||||
| | | | 1 | 2 | 3 |
| | | | 120 | 18 | 250 |
| | | | 130 | 20 | 120 |
| | | | 130 | 55 | 200 |
| | | | 130 | 71 | 300 |
| | | | 140 | 2 | 300 |
| | | | 140 | 62 | 90 |
| | | | 150 | 31 | 60 |
| | | | 150 | 70 | 20 |
| | | | 160 | 69 | 10 |
| | | | 160 | 30 | 50 |
Таблица 16
Поставки 2
-
Код_заказа
Код_клиента
Дата_поставки
110
BN
25.07.02
120
BR
12.08.02
130
BR
14.08.02
140
BS
26.08.02
150
BN
4.09.02
160
AN
18.09.02
На практике, в большинстве случаев процесс проектирования заканчивается построением третьей нормальной формы. Например, для нашего примера, после проведения нормализации можно заметить следующие улучшения:
- сведения о клиенте можно хранить, если клиент не сделал ни одного заказа;
- сведения о заказанном материале можно удалить, не опасаясь удаления данных о клиенте и заказе;
- изменение адреса клиента или даты регистрации заказа теперь требуют изменения только одной записи.
Существуют нормальные формы более высокого порядка.
Подробнее с технологией нормализации можно ознакомиться в литературе по теории реляционных баз данных [5, 8, 10, 14, 18–20, 26–29, 31].
Контрольные вопросы и задания
- Привести различия между иерархической и сетевой моделями данных.
- Охарактеризовать реляционную модель данных.
- Перечислить составные элементы реляционной модели.
- Что такое первичный ключ?
- Перечислить условия, при соблюдении которых таблицу можно считать отношением.
- В чем суть целостности сущностей?
- Определить условия ссылочной целостности.
- Определить различие между первичным и внешним ключами.
- Какое назначение внешних ключей?
- В чем различия между реляционной алгеброй и реляционным исчислением?
- Перечислить операции реляционной алгебры.
- Назвать и охарактеризовать дополнительные операции реляционной алгебры, предложенные К. Дж. Дейтом.
- Дать характеристику языку QBE.
- Перечислить операторы языка SQL.
- Выполнить сравнение языков QBE и SQL.
- В чем заключается процесс нормализации?
- Привести примеры аномалий ввода, модификации, удаления данных.
- Что такое функциональные зависимости?
- Перечислить требования нормальных форм.
- Описать этапы перехода от первой нормальной формы ко второй.
- Какая последовательность действий необходима для перехода к третьей нормальной форме?
- Составить алгебраическое выражение (или последовательность реляционных операций), необходимое для выполнения следующих запросов к базе данных поставщиков и материалов:
- получить полную информацию обо всех поставках в Москве;
- получить номера материалов, поставляемых поставщиком из Тюмени;
- получить такие пары номеров материалов, которые одновременно поставляются одним поставщиком;
- получить общее количество товаров, поставляемых поставщиком S1;
- получить названия поставщиков, которые поставляют по крайней мере один материал типа п/ш;
- получить типы материалов, поставляемых поставщиком S1.
- В компании есть несколько отделов, в каждом отделе есть несколько сотрудников, несколько проектов, несколько кабинетов. Каждый сотрудник имеет план работы (несколько заданий). Для таких заданий существует ведомость полученных вознаграждений. В каждом кабинете есть несколько телефонов. В базе данных должна содержится следующая информация:
- для каждого отдела: номер отдела, бюджет и номер сотрудника, который возглавляет этот отдел;
- для каждого сотрудника: номер сотрудника, номер текущего проекта, номер кабинета, номер телефона, название заданий вместе с датами и размерами всех оплат;
- для каждого проекта: номер проекта и бюджет;
- для каждого кабинета: номер кабинета, площадь, номера всех телефонов, установленных в кабинете.
Составить множество нормализованных отношений для представления этой информации.
- Создать реляционную схему базы данных предприятия сферы сервиса (парикмахерской, мастерской по ремонту бытовой техники, компьютерной фирмы и т.п.). Схема должна содержать как минимум семь таблиц, приведенных к третьей нормальной форме. Обосновать выбор структур таблиц, их взаимосвязь. Описать процесс нормализации таблиц.
- Дать определение данных на SQL для базы данных поставщиков и материалов.
- Сформулировать на SQL для базы данных поставщиков и материалов следующий запрос: "Получить названия поставщиков, поставляющих материал M2".
- Сформулировать на SQL следующее обновление базы данных поставщиков и материалов: "Изменить тип материала п/ш на ч/ш", "Удалить все проекты, для которых нет поставок".
- Сформулировать на QBE следующий запрос: "Вывести список клиентов, чья общая сумма годовых заказов превышает 70000".
- Сформулировать на QBE следующий запрос: "Перечислить название и цену товаров, поставка которых осуществляется после 1.03.03".
- Сформулировать на QBE следующее изменение базы данных: "Удалить сведения о клиенте с номером 3101".
4. Семантическое моделирование
Разработка базы данных в терминах реляционной модели часто сводится к сложному и неудобному для проектировщика процессу, поскольку эти модели не содержат достаточно средств для представления смысла данных. Такое положение вещей приводит к замедлению процесса разработки БД и является источником потенциальных ошибок. Семантика реальной предметной области должна независимым от модели способом представляться в сознании ее создателя. Поэтому в последнее время получило развитие семантическое моделирование. Основная цель такого подхода – организация интерфейса проектировщика, а также конечного пользователя с информационной системой на уровне представлений в пределах предметной области, а не на уровне структур данных. Наиболее популярными в настоящее время инфологическими, или как их еще называют семантическими, моделями являются объектно-ориентированная модель и модель "сущность-связь". Сочетая в себе предметную наглядность и теоретическую обоснованность, они являются мощным инструментом проектирования баз данных. Данные подходы находят все большее воплощения в конкретных системах управления базами данных.
4.1. Объектно-ориентированное проектирование
Для определения структуры БД в объектно-ориентированных терминах многими специалистами используется язык ODL. Главное назначение ODL – обеспечить запись объектно-ориентированных проектов с последующим прямым переводом в выражения объектно-ориентированной СУБД (OODBMS). Как правило, основным языком таких систем является C++ или Object Pascal, поэтому ODL необходимо переводить в выражения этих языков. ODL соответствует им обоим (но больше C++), поэтому указанный перевод достаточно прост. Значительно сложнее осуществлять перевод из ODL или проектов, реализованных в терминах модели "сущность-связь", в выражения, систем управления реляционными базами данных (RDBMS).
4.1.1. Представление объектов
При объектно-ориентированном проектировании считается, что, мир состоит из объектов – определенных наблюдаемых сущностей. Например, люди, животные, машины, авиарейсы, факультеты в институте, здания и т. д. могут пониматься как объекты. При этом каждый объект можно уникальным образом идентифицировать, чтобы отличить его от любого другого объекта.
Для построения адекватной модели предметной области, как правило, необходимо определить классы объектов, в рамках которых объекты обладают сходными свойствами. Понятия "объект" и "класс" в БД по сути дела совпадают с этими понятиями в языках объектно-ориентированного программирования (ООП).
Элементы и понятия реального мира, представляемые объектами класса, должны быть сходными. Например, можно сгруппировать всех клиентов ателье в один класс, а все заказы в другой. Нет смысла объединять клиентов и заказы в одном классе, так как между ними практически нет ничего общего, и они играют разные роли в сфере деятельности ателье.
Все объекты одного класса должны иметь одинаковый набор свойств. При программировании на объектно-ориентированном языке можно представить объекты в виде записей, как показано на рис.45.
Можно считать, что объекты имеют поля (слоты), в которых размещены значения. Такими значениями могут быть целые числа, строки или массивы, ссылки на другие объекты, а также методы, т. е. функции, применяемые к объектам.
Мы сосредоточимся на абстрактных понятиях класса и его свойств, не вдаваясь в детали реализации типа упорядочивания полей записи и даже в реальное представление объекта.
Определяя проект классов ODL, будем описывать свойства следующих видов, перечисление которых приводится далее.
- Атрибуты – свойства, типы которых строятся из исходных типов, например целых чисел или строк. Характерно то, что атрибут имеет тип, не включающий в себя ни одного класса. В ODL типы атрибутов ограничены.
- Связи – свойства, типом которых являются ссылка на объект некоторого класса или набор (например, множество) таких ссылок.
- Методы – функции, которые можно применить к объектам класса. В данном изложении применение методов не рассматривается.
4.1.2. Описания классов
Описания класса в ODL в их простейшей форме состоят из следующих элементов:
- Ключевого слова interface.
- Имени интерфейса (т.е. класса).
- Списка свойств класса, заключенного в скобки. Напоминаем, что свойства – это атрибуты, связи и методы.
Простая форма описания интерфейса:
interface <имя>{
<список свойств>}
4.1.3. Атрибуты в ODL
Свойства объектов называются атрибутами. Эти свойства описывают определенные аспекты объекта, связывая с ним значение некоторого простого типа. Например, все объекты студент могут иметь атрибут имя, типом которого является строка, а значением – имя данного человека. Эти объекты могут иметь также атрибут дата_рождения, являющийся тройкой целых чисел (т.е. структурой записи), выражающей год, месяц и день рождения данного студента.
Пример 4.1. Ниже приведено ODL-описание класса изделий ателье. Здесь оно относительно простое; позже мы расширим его.
- interface Изделие {
- attribute string назв_изделия;
- attribute integer размер;
- attribute enum Материал{ткань, мех, кожа}
тип_материала;};
Здесь и далее предполагается, что в именах допускаются кириллические символы. Данный пример чисто иллюстративный, для упрощения указывается только один размер и допускается использование только трех типов материалов.
Строка 1 описывает Изделие как класс. Ключевое слово interface используется в ODL для выражения класса. За строкой 1 следуют описания трех атрибутов, которые имеют объекты класса Изделие. Первый из них на строке 2 называется назв_изделия, его типом является string – строка символов. Предполагается, что значением атрибута назв_изделия в любом объекте Изделие будет название изделия (пальто, платье и т.д). Следующий атрибут (размер), описанный в строке 3, имеет тип целых чисел, и представляет размер изделия по установленной шкале. На строке 4 описан атрибут тип_материала, показывающий, из чего изготовлено (или изготавливается) изделие. Его тип – перечень с именем Материал. Значения атрибута перечня выбираются из списка доступных литералов, в данном примере – ткань, мех, кожа.
Определенный таким образом объект Изделие можно считать записью, или кортежем, состоящим из четырех компонентов, по одному для каждого атрибута. Например:
("Пальто", 50, кожа) является объектом Изделие.
Пример 4.2. В примере 4.1 атрибуты имеют атомарные типы. Могут быть атрибуты, типами которых являются структуры, множества или множества структур. Ниже приводится пример с неатомарным типом.
Определим класс Мастер:
- Interface Мастер {
- attribute string фамилия;
- attribute string имя;
- attribute string отчество;
- attribute Struct Адреса
{string город, integer индекс, string улица,
string дом, integer квартира} адрес;
} ;
В строках 1,2,3 определяются атрибуты фамилия, имя, отчество мастера, являющиеся строками. Строка 5 определяет атрибут адрес, имеющий тип структуры записи. Имя этой структуры Адреса, данный тип состоит из пяти полей: город, индекс, улица, дом (номер дома может содержать дроби и буквы, поэтому выбран тип string), квартира. В общем случае в ODL можно определить типы структуры записи с помощью ключевого слова Struct и фигурных скобок, выделяющих список имен полей и их типы.
4.1.4. Связи в ODL
Атрибуты объекта играют большую роль, однако иногда важнее знать то, как они связаны с объектами того же самого или другого класса.
Пример 4.3. Допустим, что к описанию класса Изделие из примера 4.1 добавляется свойство, представляющее множество работающих над ним мастеров. Поскольку сами мастера являются классом, описанным в примере 4.2, информацию о них нельзя сделать атрибутом Изделие, так как типы атрибутов не должны быть классами или строиться из классов. Множество занятых при работе над изделием мастеров, – это связь между классами Изделие и Мастер, которая выражается строкой
relationship Set<Мастер> мастера;
в описании класса Изделие. Эта строка может появиться в примере 4.2 после любой из строк – с 1 по 4. Она означает, что в каждом объекте класса Изделие есть множество ссылок на объекты класса Мастер. Множество ссылок называется мастера. Ключевое слово relationship определяет, что мастера содержит ссылки на другие объекты, а ключевое слово Set, предшествующее <Мастер>, показывает, что мастера ссылается на множество объектов Мастер, а не на единственный объект. В общем случае в ODL тип, являющийся множеством элементов другого типа Т, определяется ключевым словом Set и угловыми скобками, выделяющими тип Т.
Вообще говоря, в физических терминах множество мастера можно было бы представить списком указателей на объекты Мастер; сами объекты Мастер физически не появлялись бы в объекте Изделие. Однако на фазе проектирования БД физическое представление неизвестно и важным аспектом связи является то, что из объекта Изделие легко найти мастеров, работающим над данным изделием.
В примере 4.3 показана связь множества объектов (мастеров) с единственным объектом (изделием). Можно установить и связь единственного объекта с объектом описываемого класса. Предположим, например, что в примере 4.3 был задан тип связи Мастер, а не Set<Мастера >, с помощью строки
relationship Мастер к_мастеру;
Это значит, что с каждым изделием связан только один объект Мастер.
4.1.5. Обратные связи
Любая прямая связь подразумевает наличие обратной связи. Например, можно определять не только мастеров, занятых работой над изделиями, но и изделия, над которыми работал данный мастер. Для получения такой информации в объектах Мастер можно добавить строку
relationship Set<Изделия> от_мастера;
к описанию класса Мастер из примера 4.2. Однако в такой строке и сходном описании Изделие не учитывается очень важный аспект связи между изделиями и мастерами, а именно: если мастер S находится в множестве мастера для изделия M, то M находится в множестве от_мастера для мастера S. Это соотношение связей между множествами мастера и от_мастера выражается тем, что в описании каждой связи указывается ключевое слово inverse и имя другой связи. Если одна из связей находится в другом классе, как это обычно и бывает, ссылка на нее делается с помощью имени этого класса, за которым следуют двойное двоеточие (::) и имя связи.
Пример 4.4. Чтобы определить связь от_мастера класса Мастер как обращение связи мастера в классе Изделие, изменим описание класса Мастер следующим образом:
- interface Мастер {
- attribute string фамилия;
- attribute string имя;
- attribute string отчество;
- attribute Struct Адреса {string город, integer индекс, string улица, string дом, integer квартира} адрес;
- relationship Set<Изделие> от_мастера
inverse Изделие::мастера;};
В строке 6 выражено не только описание связи от_мастера, но и то, что данная связь имеет инверсию – Изделие::мастера. Поскольку связь мастера определена в другом классе, ее имени предшествуют двойное двоеточие и имя этого класса (Изделие). Такая нотация широко применяется при ссылках на свойства различных классов.
В примере 4.4 две обратные связи, каждая из которых соединяет объект (изделие или мастера) с множеством объектов. Как упоминалось ранее, есть связи и другого типа, соединяющие объект с единственным объектом другого класса. Понятие обращения связи при этом не изменяется. Общее правило: если связь R для класса С соединяет с объектом х класса С множество объектов y1, y2, ..., уn , то обратная к ней связь соединяет с каждым у объект х (возможно, наряду с другими объектами).
Можно представить связь R класса С с классом D в виде списка пар (или кортежей) отношения. Каждая пара состоит из объекта х из класса С и связанного с ним объекта у из класса D:
-
C
D
x1
y1
x2
y2
…
…
Если R имеет тип Set
-
C
D
y1
x1
y2
x2
…
…
Заметим, что это правило действует, даже если С и D являются одним и тем же классом. Существуют связи класса с самим собой, например связь "быть подчиненным" класса "сотрудники" с самим собой.
4.1.6. Множественность связей
Необходимо учитывать, что данный объект связан с единственным объектом или он может быть связан с множеством других объектов. В ODL эти возможности определяются тем, применяется или нет в описании связи оператор множества типа Set. При наличии обратимой пары связей существует четыре возможности: связь может иметь тип "один-к-одному", "один-ко-многим", или "многие-ко-многим".
Рассмотренная связь между мастерами и изделиями относится к типу "многие-ко-многим" и не является уникальной ни в одном направлении: бывает над изделием работают несколько мастеров и один мастер занят со множеством изделий. Следующий пример является развитием предыдущих примеров. В нем вводится класс Цех, представляющий пошивочные цеха, работающие с различными изделиями.
Пример 4.5. Ниже приводится описание трех классов: Изделие, Мастер и Цех. Первые два из них уже были введены в примерах 4.1 и 4.2. Объекты цехов имеют атрибуты название и адрес, появляющиеся в строках 14 и 15. Заметим, что здесь типом адресов является строка, а не структура, использованная для атрибута адрес класса Мастер. В различных классах можно использовать атрибут с одним и тем же именем, но с разными типами.
- interface Изделие {
- attribute string назв_изделия;
- attribute integer размер;
- attribute enum Материал{ткань, мех, кожа} тип_материала;
- relationship Set<Мастер> мастера
inverse Мастер::от_мастера;
- relationship Цех выполняется_в
inverse Цех::обеспечивает;
};
- interface Мастер {
- attribute string фамилия;
- attribute string имя;
- attribute string отчество;
- attribute Struct Адреса {string город, integer индекс, string улица, string дом, integer квартира} адрес;
- relationship Set<Изделие> от_мастера
inverse Изделие::мастера;
};
- interface Цех{
- attribute string название;
- attribute string адрес;
- relationship Set<Изделие> обеспечивает
inverse Изделие::выполняется_в;
};
В строке 6 показана связь выполняется_в между изделиями и цехами. Поскольку ее типом является Цех, а не Set <Цех >, каждое изделие изготавливает только один цех. Обращение данной связи показано в строке 16 – это связь обеспечивает между цехами и изделиями. Ее типом является Set<Изделие>, поэтому каждый цех обеспечивает множество изделий – возможно, ни одно, только одно или большее число изделий.
Требования уникальности связи и ее обращения называются множественностью связей. Наиболее распространенные варианты:
- Связь типа "многие-ко-многим" класса С с классом D – это связь, в которой с каждым объектом класса С ассоциируется множество объектов класса D, а в ее обращении с каждым объектом класса D ассоциируется множество объектов класса С. В описании, приведенном в примере 4.5, мастера – это связь типа "многие-ко-многим" между классом Изделие и классом Мастер; такой же является связь от_мастера между классами Мастер и Изделие.
В любом направлении связи допускается пустое множество.
- Связь типа "многие-к-одному" класса С с классом D – это связь, в которой для каждого объекта класса С существует уникальный объект класса D, но в ее обращении с каждым объектом класса D связаны многие С. В примере 4.5 выполняется_в – это связь типа "многие-к-одному" класса Изделие с классом Цех. Обратная ей связь – это связь типа "'один-ко-многим" класса D с классом С. В том же примере обеспечивает – связь типа "один-ко-многим" класса Цех с классом Изделие.
- Связь типа "один-к-одному" класса С с классом D – это связь, в которой для каждого объекта класса С существует уникальный объект класса D.
В обратной связи каждый объект класса D связан с уникальным объектом класса С. В описание из примера 4.5 можно добавить класс Начальник, представляющий начальников цехов. Предполагается, что каждый цех имеет единственного начальника и ни один человек не может быть начальником более чем одного цеха. Значит, связь между цехами и их начальниками имеет тип "один-к-одному" в обоих направлениях.
При описании связей следует иметь в виду, что связь типа "многие-к-одному" – это частный случай связи типа "многие-ко-многим", а связь типа "один-к-одному" – частный случай связи типа "многие-к-одному". Любое полезное свойство связей типа "многие-ко-многим" применимо к связям типа "многие-к-одному", а полезные свойства последних верны и для связей типа "один-к-одному". Например, структура данных для представления связей типа "многие-к-одному" подходит для связей типа "один-к-одному", но может быть непригодна для связи типа "многие-ко-многим".
Используя термины типа "уникальный" или "один" при определении связей типа "многие-к-одному" или "один-к-одному" необходимо учитывать некоторую неопределенность. Важно считать, что "уникальный" или "один" элемент реально существует. Например, для каждого изделия реально существует пошивочный цех, а цех возглавляет реальный начальник. Однако есть все основания считать, что в реальности уникального объекта не существует. Например, цех может временно работать без начальника или же мы можем не знать какому цеху относится конкретное изделие.
Таким образом, обычно допускается, что предполагаемое значение связанного объекта может отсутствовать. Значение "null" часто допускается в БД там, где предполагается наличие истинного значения. Например, в терминологии традиционного программирования указатель "null" может стоять там, где предполагается указатель на единственный объект.
4.1.7. Типы в ODL
Средства ODL предоставляют проектировщику систему типов, подобную системам типов языка С или других популярных языков программирования. Система типов строится из базовых типов, которые определены сами по себе, с помощью конкретных рекурсивных правил (сложные типы строятся из более простых). Базовые типы ODL:
- Атомарные типы: целое число с плавающей точкой, символ, строка символов, булево выражение и перечисление. Последний тип – это список имен, объявленных синонимами целых чисел. Перечисление содержится в строке 5 примера 4.4, где имена ткань, мех, кожа в результате были определены как синонимы чисел 0, 1, 3.
- Типы интерфейса, например Изделие и Мастер, являются реальными структурами с компонентами для каждого атрибута и каждой связи данного интерфейса. Эти имена представляют сложные типы, определяемые с помощью перечисленных ниже типов, но их можно считать базовыми.
Базовые типы комбинируются в структурные типы с помощью следующих конструкторов типов:
- Множество. Если T -любой тип, то Set<T> обозначает тип, значениями которого являются все конечные множества элементов типа Т.
- Мультимножество. Если Т – любой тип, то Bag<T > обозначает тип, значениями которого являются все мультимножества элементов типа Т. Мультимножество допускает многократное повторение одного и того же элемента. Например, {1, 2, 1} – это мультимножество, а не множество, так как 1 повторяется в нем дважды.
- Список. Если Т– любой тип, то List<T> обозначает тип, значениями которого являются конечные списки, состоящие из нуля или более элементов типа Т. В специальном случае тип string является сокращением типа List<char>.
- Массив. Если Т– любой тип, то Аггау<Т> обозначает тип, элементами которого является массив из i элементов типа Т. Например, Array<char,10> обозначает символьную строку длиной 10.
- Структуры. Если Т1,T2, ..., Тn являются типами, a F1, F2, ..., Fn именами полей, то
Struct N {Т1F1,T2F2…,TnFn}
обозначает тип с именем N, элементами которого служат структуры, содержащие п полей; i-е поле имеет имя Fi и тип Тi. Например, строка 10 в примере 4.4 показывает тип структуры с именем Адрес с пятью полями.
Для того чтобы различать множества, мультимножества и списки следует помнить, что элементы множества не упорядочены и каждый из них входит в данное множество только один раз. Мультимножество допускает более одного вхождения любого элемента, но элементы и их вхождения не упорядочены. В списке может быть несколько вхождений одного и того же элемента, но все вхождения в нем упорядочены. Значит, {1, 3, 1} и {3, 1, 1} – это одно и то же мультимножество, но {1, 3, 1} и {3, 1, 1} – это разные списки.
Первые четыре типа – множество, мультимножество, список и массив – называются типами множеств. Существуют правила, определяющие, какие типы можно ассоциировать с атрибутами, а какие со связями.
Построение типа атрибута начинается с атомарного типа или со структуры, полями которой являются атомарные типы. Затем по выбору можно применить тип множества к исходному атомарному типу структуры.
Тип связи – это или тип интерфейса, или тип набора, примененный к типу интерфейса.
Важно помнить, что типы интерфейса могут не появляться в типе атрибута, а атомарные типы – в типе связи. В этом отличие атрибутов и связей друг от друга. Разница между ними еще и в том, как строятся для них сложные типы: и атрибут, и связь допускают произвольный тип множества в качестве последнего оператора, но тип структуры допустим только в атрибутах.
Пример 4.6. Возможные типы атрибутов:
- integer.
- Struct N {string fieldl, integer field2}.
- List<real>.
- Array<Struct N {string fieldl, integer field2}>.
Здесь 1 – атомарный тип, 2 – структура атомарных типов, 3 – множество атомарного типа, а 4 – множество структур, построенных из атомарных типов.
Допустим, что доступными базовыми типами являются имена интерфейсов Изделие и Мастер. Тогда можно построить типы связи Изделие или Bag<Мастер>. Однако следующие типы связей недопустимы:
- Struct N {Изделие fieldl, Мастер field2}. Типы связей не могут включать в себя структуры.
- Set<integer>. Типы связей не могут содержать атомарные типы.
- Set<Array<Мастер>. Типы связей не могут содержать два применения типов множества (их не могут содержать и типы атрибутов).
4.1.8. Проектирование с использованием ODL
В данном разделе рассматриваются некоторые полезные принципы проектирования с использованием объектно-ориенти-рованного подхода.
Правильность
Самое важное: проект должен быть адекватным конкретной предметной области, правильно отображать реальный мир. Классы или множества сущностей и их атрибуты, должны отражать реальные объекты. Нельзя приписывать мастеру-портному атрибут "число цилиндров", хотя это имеет смысл для класса автомобилей. Любые установленные связи должны соотноситься с нашими знаниями о моделируемой части реального мира.
Пример 4.7. Если определяется связь мастер_для между Мастер и Изделие, она должна быть типа "многие-ко-многим", так как наблюдения за реальным миром показывают, что мастера могут быть заняты работой над многими изделиями, и изделия могут (не обязательно, но могут) выполняться несколькими мастерами. Неверно определять эту связь как " связь типа "один-к-одному".