|
Программирование >> Проектирование баз данных
этой таблице). Достаточных оснований для того, чтобы эти две сущности были отдельными, нет. Конструкции такого типа иногда встречаются при разработке моделей для объединения двух систем, в которых одна сущность называется по-разному. Поскольку здесь мы говорим о логической, а не о физической модели, эти сущности необходимо объединить и присвоить им общее имя. Рис 3.25. Два примера отношений один к одному (унарных) Отношение между С и D на рис. 3.25 является допустимым. Примером такого отношения является отношение между персональным компьютером и мышью. ПК может работать как с мышью, так и без нее, тогда как мышь может работать только с компьютером. Здесь нужно принять проектное решение: будем ли мы реализовывать сущности ПК и мышь в виде отдельных таблиц или же объединим их? Некоторые достоинства {+) и недостатки (-) обоих вариантов приведены в табл. 3.5. Табллица 3.5. Характеристики одно- и двухтабличного решения задачи с отношением один к одному Однотабличное решение Двухтабличное решение Обслуживающие программы Целостность данных Изолированные сущности (+) Для обслуживания персональных компьютеров и мыши нужно написать только одну обслуживающую программу (-) Нельзя использовать ограничения NOT NULL, для того чтобы сделать значения относящихся к мыши столбцов обязательными (-) Если мы сделаем мышь расширением ПК, то как вести информацию о мыши, не подключенной в данный момент к ПК? (-) Нужно написать две обслуживающие программы (+) Можно задать столбцы с обязательными значениями при помощи ограничений NOT NULL (+) Объекты могут существовать в изоляции
При использовании однотабличного рещения атрибуты мыщи становятся атрибутами ПК. Все атрибуты мыщи, которые были обязательными, становятся необязательными атрибутами новой сущности ПК-мышь , чтобы > гесть слушй, когда ПК не имеет мыши. Можно реализовать эти правила через триггеры и дополнительный атрибут, указывающий, работает ли ПК в данный момент с мышью. Впрочем, это несколько громоздкое решение. Отношение, обязательное на обеих сторонах (рис. 3.26), довольно нетрадиционно, но, конечно, допустимо. Типичный пример - заказ и строка заказа. Строка заказа не может существовать сама по себе, без заказа, в который она помещается. Заказ без строки заказа - вообще не заказ как таковой, мы будем напрасно тратить время, пытаясь доставить пустое место или оформляя документы для него! Рис. 3.26. Два примера отношений, обязательных на обеих сторонах Проблема здесь состоит в наличии ситуации курица и яйцо . Заказ нельзя создать без строки заказа, тогда как для строки заказа должен существовать заказ, в который она будет помещена. Что же создавать в первую очередь? На первый взгляд, кажется, что ответ должен быть следующим: порядок создания не имеет значения, если обе эти сущности создаются в одной транзакции, а при удалении строки выполняется проверка, определяющая, пуст ли теперь заказ; если пуст, то заказ тоже удаляется. Но не всегда все происходит так, как кажется... Давайте обсудим эту ситуацию с точки зрения проектирования таблиц базы данных Oracle. У нас будет внешний ключ из таблицы ORDER LTNES к таблице ORDERS. Значения соответствующих столбцов можно сделать обязательными с помощью ограничения NOT NULL. Благодаря этому все строки таблицы ORDER LINES будут снабжены номером заказа. Как ввести правило, согласно которому каждому заказу из таблицы ORDERS должна соответствовать строка в таблице ORDER LINES? На первый взгляд очевидно, что следует использовать триггеры. Необходимо создать триггер уровня строки на таблице ORDERS, запускающийся перед вставкой строки и проверяющий наличие связанной строки в таблице ORDER LINE. Если такой строки нет, операция вставки выполняться не будет. Триггер уровня строки на таблице ORDER LINES, запускающийся после удаления строки, должен проверять наличие в ORDER LINES других строк, относящихся к тому же заказу. Если таких строк нет, то заказ можно удалить из таблицы ORDERS. Однако, к сожалению, ни один из этих триггеров работать не будет. К сведению При вставке строк у нас все равно остается проблема курицы и яйца . Если первым создается заказ, то этот триггер не найдет в таблице ORDER LINES ни одной строки, относящейся к этому заказу, так как вставка в эту таблицу еще не проводилась. Если первыми вставляются строки заказа, то наще ограничение по внещнему ключу не сработает, так как родительский элемент еще не вставлен. Триггер для удаления не сработает, потому что мы пытаемся выбрать элемент в той таблице, из которой была инициирована операция удаления (ORDER LINES). Поскольку эта таблица рассматривается как мутирующая во время работы триггеров уровня строки, то возникнет ощибка. Для проблемы с удалением есть рещение. Мы используем триггер уровня строки, чтобы просто запомнить событие (вставку или удаление) в глобальной переменной пакета PL/SQL и возлагаем проверку на триггер AFTER INSERT/DELETE уровня строки. (Этот прием подробно описан в приложении Б.) Проблему со вставкой решить гораздо труднее. Здесь существует два пути. Можно поместить проверку в приложение (приложения), которые создают заказы и строки, и гарантировать таким образом, что пустые заказы в таблице ORDERS не создаются. Можно попытаться достичь компромисса с пользователем или аналитиком. Если они разрешат создание пустого заказа, то мы напишем подпрограмму, которая каждый вечер в пакетном режиме будет удалять пустые заказы. Если запускать эту подпрограмму до всех других критшшых программ обработки и подготовки отчетов, то заказы-призраки никакого вреда не принесут. Впрочем, ни одно из этих решений нельзя назвать идеальным. Облава на потерянную дугу Если сущность имеет набор взаимоисключающих отношений с другими сущностями, то говорят, что эти отношения находятся в дуге. Рассмотрим пример из банковского приложения, проиллюстрированный на рис. 3.27. Эту диаграмму следует читать так: Каждый счет должен быть оформлен или на одно и только одно физическое лицо, или на одно и только одно юридическое лицо .
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |