Три манифеста баз данных ретроспектива и перспективы
1942e8f8

Язык определения объектов ODL


ODL является языком определения данных для объектной модели ODMG 27. ODL используется исключительно для описания интерфейсов типов приложения, а не для программирования реализации. Это не язык программирования, а всего лишь язык описания схем баз данных.

“Программа” на языке ODL – это набор определений типов, констант, исключительных ситуаций, интерфейсов типов и модулей. Не углубляясь в детали и не приводя синтаксических правил, остановимся на наиболее интересных (с точки зрения автора этой статьи) особенностях ODL.

Язык обеспечивает исключительно мощные возможности для определения литеральных типов. С точки зрения автора, наиболее интересны типы коллекций. Можно определить четыре разновидности типов коллекций. Типы категории set – это обычные типы множеств. Типы категории bag – эти типы мультимножеств (в значениях которых допускается наличие элементов-дубликатов). Значениями типов категории list являются упорядоченные списки значений (среди них допускаются дубликаты). Наконец, значениями типы dictionary являются множества пар <ключ, значение> , причем все ключи в этих парах должны быть различными. Определения типов имеют рекурсивную природу. Например, можно определить тип множества структур, элементами которых будут являться списки мультимножеств и т.д.

Синтаксические правила, относящиеся к определению объектных типов, требуют достаточно подробных разъяснений. К сожалению, в стандарте ODMG 3.0 этих разъяснений явно недостаточно. Поэтому дальнейший текст этого пункта является некоторым домыслом автора этой статьи, который логичен, но не обязательно соответствует истинным взглядам авторов стандарта (проверить это не представляется возможным).28

Во-первых, объектный тип можно определить с помощью двух разных синтаксических конструкций языка ODL – interface и class

29. Определение класса отличается от определения интерфейса наличием двух необязательных разделов: extends и type _ property _ list . В действительности, наиболее важным отличием класса от интерфейса является возможность наличия второго из этих разделов.
В списке свойств30 могут присутствовать элементы extent и key . В спецификации модели данных ODMG 3.0 (хотя это и не отражается явно в синтаксисе ODL ) говорится, что для каждого класса может быть определен только один экстент, являющийся множеством всех объектов этого класса, которые после создания должны сохраняться в базе данных.31

Ключ – это набор свойств объектного класса, однозначно идентифицирующий состояние каждого объекта, входящего в экстент класса (это аналог возможного ключа реляционной модели данных). Для класса может быть объявлено несколько ключей, а может не быть объявлено ни одного ключа даже при наличии определения экстента. В последнем случае в экстенте класса могут существовать разные объекты с одним и тем же состоянием.32



Рис. 2.3. Пример иерархии объектных типов и их экстентов

Далее, хотя и интерфейсы, и классы являются средствами определения объектных типов, между ними проводится жесткое различие. Допускается создание объектов только тех объектных типов, которые определены как классы. Объектные типы, определенные как интерфейсы, могут использоваться только для порождения новых объектных типов (интерфейсов и классов) на основании (вообще говоря) множественного наследования. Классы могут определяться на основе (вообще говоря) множественного наследования интерфейсов и одиночного наследования классов.

Механизм наследования от интерфейсов называется в ODMG наследованием IS - A, а механизм наследования от классов – extends . Прежде чем попытаться пояснить этот подход, приведем пример графа наследования интерфейсов и классов, в котором также показывается место существующих экстентов и объектов (рис. 2.3).

На рис. 2.3 “жирными” стрелками показаны связи объектных типов по наследованию IS - A . Обычные стрелки показывают связи по наследованию extends . Пунктирные стрелки соответствуют связям экстентов и соответствующих классов. Обратите внимание, что на этом рисунке у каждого из классов, входящих в иерархию, определен свой собственный экстент.




Как демонстрирует рисунок, в модели ODMG поддерживается семантика включения, означающая, что экстент любого подкласса является подмножеством экстента любого своего суперкласса (прямого или косвенного). Если у некоторого подкласса свой собственный экстент не определен, то с объектами этого подкласса можно работать только через экстент какого-либо суперкласса. Стандарт не требует обязательного определения экстента. В этом случае ответственность на поддержку работы с множествами объектов ложится на прикладного программиста (для этого можно использовать типы коллекций).

Итак, при порождении подкласса путем наследования extends от некоторого суперкласса подкласс наследует экстент и набор ключей суперкласса. Как мы уже заметили, для подкласса можно определить свой собственный экстент. Что же касается возможности переопределения ключей, то в стандарте отсутствуют явные указания о возможности или невозможности этого действия. Однако очевидно, что если бы было разрешено полное переопределение набора ключей для экстента подкласса, то это противоречило бы семантике включения. По мнению автора данной статьи, по этому поводу можно трактовать ODL одним из двух способов:

(1) Если в некотором подклассе определен набор ключей, то в любом его подклассе определение ключей запрещается.

(2)   Если в некотором подклассе определен набор ключей, то определение ключей в любом его подклассе приводит к расширению для этого подкласса набора ключей суперкласса.

Теперь немного поговорим о связях. Связи определяются между объектными типами. В модели ODMG поддерживаются только бинарные связи, т.е. связи между двумя типами. Связи могут быть разновидностей “один-к-одному”, “один-ко-многим” и “многие-ко-многим” в зависимости от того, сколько экземпляров соответствующего объектного типа может участвовать в связи.

Связи явно определяются путем указания путей обхода (traversal paths ). Пути обхода указываются парами, по одному пути для каждого направления обхода связи33. Например, в базе данных “служащие-отделы-проекты” служащий работает (works ) в одном отделе, а отдел состоит (consists of ) множества служащих.


Тогда путь обхода consists _ of должен быть определен в объектном типе DEPT , а путь обхода works – в типе EMP . Тот факт, что пути обхода относятся к одной связи, указывается в разделе inverse обоих объявлений пути обхода. В нашем случае определения типов DEPT и EMP могли бы выглядеть следующим образом:

class DEPT {

     ...
     relationship set <EMP> consists_of
          inverse EMP :: works
     ... }

class EMP {

     ...
     relationship DEPT works
          inverse DEPT :: consists_of
     ... }

Как видно, это связь “один-ко-многим”. Путь обходаconsists _ of ассоциирует экземпляр типа DEPT со множеством экземпляров типа EMP , а путь обхода works ассоциирует экземпляр типа EMP с экземпляром типа DEPT . Пути обхода, ведущие к коллекциям объектов, могут быть упорядоченными или неупорядоченными в зависимости от вида коллекции, указанному в объявлении пути обхода. В приведенном выше примере consists _ of является неупорядоченным путем обхода.

В ООСУБД, соответствующей стандарту ODMG , должна поддерживаться ссылочная целостность связей. Это означает, что при ликвидации любого объекта, участвующего в связи, должны ликвидироваться и все пути обхода, ведущие к этому объекту. Такой подход гарантирует, что приложения не смогут воспользоваться путями обхода, ведущими к несуществующим объектам.

Наконец, хотя это явно не отражено в синтаксисе языка ODL (по непонятным для меня причинам), наряду с набором генераторов литеральных типов коллекций set < b>t > , bag < t > , list < t > , array < t > и dictionary < t , v > поддерживается аналогичный набор генераторов объектных типов коллекций – Set < t > , Bag < t > ,List < t > , Array < t > и Dictionary < t , v > . В отличие от литералов-коллекций объекты-коллекции обладают объектными идентификаторами и свойством изменчивости. Во всех случаях требуется, чтобы все элементы коллекции были одного типа, литерального или объектного. И для литеральных, и для объектных коллекций поддерживается возможность итерации

коллекции с перебором элементов коллекции либо в порядке, определяемом системой (для множеств и мультимножеств), либо в порядке, предполагаемом видом коллекции (для списков, массивов и словарей).


Содержание раздела