|
| ||||||||||||
| ||||||||||||
|
2008 г.
Базы данных. Вводный курсСергей Кузнецов11.3. Ограничения целостности и язык OCLКак уже отмечалось, в диаграммах классов могут указываться ограничения целостности, которые должны поддерживаться в проектируемой БД. В UML допускаются два способа определения ограничений: на естественном языке и на языке OCL. На рис. 11.13 показана простая диаграмма классов
В данном случае накладывается ограничение на состояние объектов классов 11.3.1. Общая характеристика языка OCLБолее точный и лаконичный способ формулировки ограничений обеспечивает язык OCL (Object Constraints Language). Вот общая характеристика этого языка. Из языка UML58) в OCL заимствованы, в первую очередь, следующие концепции:
Для понимания языка OCL существенны определяемые в UML традиционные для объектных моделей данных различия между объектом некоторого класса и значением некоторого типа:
В дополнение к скалярным типам данных, заимствованным из UML, в OCL предопределены структурные типы, которые являются разновидностями типов коллекций (collection):
В OCL элементами каждого из трех типов коллекций могут быть либо объекты, либо значения. Язык OCL предназначен, главным образом, для определения ограничений целостности данных, соответствующих модели, которая представлена в терминах диаграммы классов UML. OCL может применяться для определения ограничений, описывающих пред- и постусловия операций классов, и ограничений, представляющих собой инварианты классов. При проектировании реляционных баз данных возможность определения пред- и постусловий операций вряд ли может оказаться существенной62). С точки зрения определения ограничений целостности баз данных более важны средства определения инвариантов классов. 11.3.2. Инвариант классаПод инвариантом класса в OCL понимается условие, которому должны удовлетворять все объекты данного класса. Если говорить более точно, инвариант класса – это логическое выражение, вычисление которого должно давать context <class_name> inv: <OCL-выражение> Здесь Заметим, что OCL является типизированным языком, поэтому у каждого выражения имеется некоторый тип. Естественно, что OCL-выражение в инварианте класса должно быть логического типа. В общем случае OCL-выражение в определении инварианта основывается на композиции операций, которым посвящена большая часть определения языка. В спецификации языка эти операции условно разделены на следующие группы:
Последовательно обсудим эти группы операций. Операции над значениями предопределенных типов данныхПолагая очевидной семантику предопределенных скалярных типов данных и операций над ними, ограничимся лишь их перечислением. В OCL поддерживаются следующие заимствованные из определения UML скалярные типы данных: Boolean, Integer, Real и String. Операции над объектамиВ OCL определены три операции над объектами:
Для записи этих трех операций используется «точечная нотация». Например, результатом выражения вида <объект>.<имя атрибута> является текущее значение атрибута с именем Результатом применения к объекту операции перехода по соединению (экземпляру связи-ассоциации) является коллекция, содержащая все объекты, которые ассоциированы с данным объектом через указываемое соединение. Это соединение идентифицируется именем роли, противоположной по отношению к данному объекту. Таким образом, синтаксис выражения перехода по соединению следующий: <объект>.<имя роли, противоположенной по отношению к объекту> 11.3.3. Операции над множествами, мультимножествами и последовательностямиВ OCL поддерживается обширный набор операций над значениями коллекционных типов данных. Обсудим только те из них, которые являются уместными в контексте данной лекции. Синтаксически операции над коллекциями записываются в нотации, аналогичной точечной, но вместо точки используется стрелка ( <коллекция> Операция selectВ OCL определены три одноименных операции Операция collectАналогично набору операций Операции exists, forAll, sizeВ OCL определены три одноименных операции Операции union, intersect, symmetricDifferenceПараметрами двуместных операций 11.3.4. Примеры инвариантовВ заключение обзора языка OCL приведем примеры четырех инвариантов, выраженных на этом языке. Будем основываться на диаграмме классов, показанной на рис. 11.14.
Пример 11.1. Определить ограничение «возраст служащих должен быть больше 18 и меньше 100 лет». context Служащий inv: self.возраст > 18 and self.возраст < 100 Условие инварианта накладывает требуемое ограничение на значения атрибута Пример 11.2. Выразить на языке OCL ограничение, в соответствии с которым в отделах с номерами больше 5 должны работать служащие старше 30 лет. context Отдел inv: self.номер В этом случае условное выражение инварианта будет вычисляться для каждого объекта класса Тот же инвариант можно сформулировать в контексте класса context Сотрудник inv: self.возраст > 30 or self.отдел.номер Здесь следует обратить внимание на подвыражение Пример 11.3. Определить ограничение, в соответствии с которым у каждого отдела должен быть менеджер, и любой отдел должен быть основан не раньше соответствующей компании: context Отдел inv: self.служащий Здесь должность – атрибут класса Обратите внимание, что в этом случае снова законным является подвыражение Пример 11.4. Условие четвертого инварианта ограничивает максимально возможное количество служащих компании числом 1000: context Компания inv: self.отдел Здесь полезно обратить внимание на использование операции 11.3.5. Плюсы и минусы использования языка OCL при проектировании реляционных баз данныхПлюсы и минусы использования языка OCL при проектировании реляционных БД очевидны. Язык позволяет формально и однозначно (без двусмысленностей, свойственных естественным языкам) определять ограничения целостности БД в терминах ее концептуальной схемы. Скорее всего, наличие подобной проектной документации будет полезным для сопровождения БД, даже если придется преобразовывать инварианты OCL в ограничения целостности SQL вручную. К отрицательным сторонам использования OCL относится, прежде всего, сложность языка и неочевидность некоторых его конструкций. Кроме того, строгость синтаксиса и линейная форма языка в некотором роде противоречат наглядности и интуитивной ясности диаграммной части UML. Да, в инвариантах OCL используются те же понятия и имена, что и в соответствующей диаграмме классов, но используются совсем в другой манере. И последнее. Трудно доказать или опровергнуть как предположение, что на языке OCL можно выразить любое ограничение целостности, которое можно определить средствами SQL, так и утверждение, что на языке OCL нельзя выразить такой инвариант, для которого окажется невозможным сформулировать эквивалентное ограничение целостности на языке SQL. Лично мне неизвестны работы, в которых бы сравнивалась выразительная мощность этих языков в связи с ограничениями целостности реляционных БД. 11.4. Получение схемы реляционной базы данных из диаграммы классов UMLЕсли не обращать внимания на различия в терминологии64), то здесь выполняются практически те же шаги, что и в случае преобразования в схему реляционной БД ER-диаграммы. Поэтому ограничимся только некоторыми рекомендациями, специфичными для диаграмм классов. Рекомендация 1. Прежде чем определять в классах операции, подумайте, что вы будете делать с этими определениями в среде целевой РСУБД. Если в этой среде поддерживаются хранимые процедуры, то, возможно, некоторые операции могут быть реализованы именно с помощью такого механизма. Но если в среде РСУБД поддерживается механизм определяемых пользователями функций, возможно, он окажется более подходящим. Рекомендация 2. Помните, что сравнительно эффективно в РСУБД реализуются только ассоциации видов «один ко многим» и «многие ко многим». Если в созданной диаграмме классов имеются ассоциации «один к одному», следует задуматься о целесообразности такого проектного решения. Реализация в среде РСУБД ассоциаций с точно заданными кратностями ролей возможна, но требует определения дополнительных триггеров, выполнение которых понизит эффективность. Рекомендация 3. Для технологии реляционных БД агрегатные и в особенности композитные ассоциации неестественны. Подумайте о том, что вы хотите получить в реляционной БД, объявив некоторую ассоциацию агрегатной. Скорее всего, ничего. Рекомендация 4. В спецификации UML говорится о том, что, определяя однонаправленные связи, вы можете способствовать эффективности доступа к некоторым объектам. Для технологии реляционных баз данных поддержка такого объявления вызовет дополнительные накладные расходы и тем самым снизит эффективность. Рекомендация 5. Не злоупотребляйте возможностями OCL. Диаграммы классов UML – это мощный инструмент для создания концептуальных схем баз данных, но, как известно, все хорошо в меру. 58 Хотя язык OCL формально считается частью UML, он специфицирован в отдельном документе, в котором присутствуют ссылки на другие части спецификации UML, а также вводятся собственные понятия и определения. 59 Следует заметить, что ни в спецификации UML, ни в описании какой-либо другой объектной модели никогда прямо не говорится, что в операциях над множествами объектов в действительности участвуют идентификаторы объектов. Но другого понимания не существует. 60 Обратите внимание, что хотя, в UML допускаются 61 В контексте проектирования реляционных БД (если не иметь в виду использование объектно-реляционных СУБД) последняя разновидность типа коллекции является бессмысленной, поскольку в реляционных БД упорядоченность не поддерживается. Поэтому мы не будем обсуждать детали операций над последовательностями. 62 Если снова не иметь в виду использование объектно-реляционных СУБД. 63 Для коллекций значений возможно также применение операций 64 Очевидным аналогом класса является тип сущности, а аналогом связи-ассоциации — связь в смысле ER-модели. Кстати, различия и беспорядок в терминологии действительно удручают. В ER-модели связь (relationship) — это ассоциация (association) между двумя типами сущности. В UML ассоциация (association) — это один из видов связи (relationship). Да еще зачем-то в UML введен специальный термин link для обозначения экземпляра ассоциации. И снова хотелось бы использовать в качестве русского эквивалента термин связь, но он уже безнадежно занят, и приходится переводить link как соединение. Это, конечно, не противоречит смыслу, но тоже очень плохо, поскольку в области реляционных БД термин соединение и без этого имеет два разных смысла – операции соединения и соединения с сервером баз данных. Мне очень жаль переводчиков книг, посвященных UML.
|
|
CITForum © 1997–2025