Объектные модели данных
10.2 Объектная модель данных
В настоящее время имеется два основных претендента на ведущую роль в применении объектов в базах данных. Это объектно-реляционные базы, стандартизованные в рамках SQL3 и объектные базы в стандартах консорциума ODMG (Object Data Management Group).
Объектную модель ODMG можно считать расширением языков ООП на персистентные классы, объекты которых могут сохраняться в базе данных. Естественно, в СУБД, реализующей такую модель, необходимо создать свою систему хранения объектов.
В объектно-реляционных базах понятие таблицы распространяется на таблицы с многоуровневыми шапками, а система хранения данных представляет расширяемую модель хранения реляционного типа.
10.2.1 Особенности архитектуры Cache. Система классов
Объектная система Cache построена на объектном расширении языка ObjectScript, который изначально был персистентным. Уникальная особенность системы в том, что она позволяет работать с данными одновременно в объектной, реляционной и иерархической моделях, не заботясь ни о каких отображениях (mappings). Заметим, что сама фирма Intersystems, скорее, не согласится с такой трактовкой её детища. Для неё Cache, в первую очередь, объектная СУБД. Однако, легко получаемые в Cache дедуктивная, полуструктурированная и другие модели, включая так называемые NoSQL, позволяют считать Cache, по крайней мере, потенциально полимодельной СУБД.
Универсальная архитектура Cache
В универсальной архитектуре Cache (рисунок 10.8, таблица 10.2) и объекты и таблицы отображаются в многомерные структуры, хранением которых заведует механизм многомерной памяти. Унифицированные структуры данных доступны и серверу объектов и SQL-серверу. Программное обеспечение промежуточного уровня может обращаться к одному из этих серверов. Шлюз SQL позволяет обмениваться данными с другими базами реляционного типа.
Middleware/Application | Промежуточное ПО/Приложение |
SQL Database | База данных SQL |
Objects | Объекты |
Unified Data Arhitecture | Унифицированная архитектура данных |
Multidimensional Storage Engine | Средство многомерного хранения |
SQL-доступ в Cache допускает использование интерфейсов ODBC, JDBC и ADO.Net. Поддерживается связывание данных с объектно-ориентированными языками, включая Java, C# и C++.
Система классов
Как всегда, класс задаёт шаблон, по которому создаются объекты определённого им типа. Объект — это экземпляр класса. Метод представляет собой функции или процедуры класса или объекта, определяющие его поведение. Свойства класса считаются определяющими состояния класса, но они не используются для идентификации объектов, как в реляционной модели.
Можно считать понятия класса и типа синонимами. Как и в естественных языках, объёмы понятий-синонимов перекрываются, но не совпадают. Предопределённые типы данных инкапсулированы, то есть их определения не доступны для изменения. Однако, пользовательские типы открыты. Обычно классы выстраиваются в иерархию наследования. У типов этого нет. Типы данных не могут содержать свойств. Для типов данных невозможно создавать экземпляры.
В Cache принята следующая терминология. Классы вообще подразделяются на классы типов данных и классы объектов (рисунок 10.9). Классы типов данных определяют допустимые значения констант (литералов) и позволяют их контролировать. Классы типов данных содержат предопределённые наборы методов проверки и приведения значений атрибутов к другим типам.
Классы объектов делятся на зарегистрированные и незарегистрированные. Каждый класс объектов имеет уникальное имя в пределах пространства имён, свойства, методы, параметры, запросы и индексы.
Незарегистрированные классы (Non-Registered Class) предназначены для создания пользовательской объектной системы и не имеют предопределенного поведения. Объектные ссылки для них не формируются. Разработка функций незарегистрированного класса —обязанность разработчика.
Объекты зарегистрированных классов и их наследники имеют объектную ссылку OREF (object reference), идентифицирующую объект, находящийся в памяти компьютера.
Хранимые объекты имеют вторую ссылку OID (object ID), идентифицирующую объект на физическом носителе.
Зарегистрированные классы это временные классы, обладающие предопределенным поведением. Реализуется оно набором встроенных функций, наследуемых из системного класса %RegisteredObject и отвечающих, в частности, за создание новых объектов и за управление размещением объектов в памяти. Заметим, что знак процента в имени означает, что класс или метод системные.
У каждого зарегистрированного объекта имеется уникальная объектная ссылка OREF, обеспечивающая доступ к объекту в памяти.
Зарегистрированные классы могут быть ещё хранимыми и встраиваемыми. Первые хранятся независимо и потому имеют уникальную не изменяемую объектную ссылку OID, по которой объект может быть найден на диске, и ссылку OREF.
Встраиваемые классы могут попасть на диск только в составе хранимого класса и потому OID не имеют, но при выгрузке в память для них создаётся соответствующая ссылка OREF. Встраиваемые классы наследуют свое поведение от класса %Serial.
Хранимые классы наследуют свое поведение от класса %Persistent, используя обширный набор его методов, включающий создание объекта, подкачку объекта из базы в память, удаление объекта и т.д. Каждый экземпляр хранимого класса имеет два уникальных идентификатора — OID и OREF.
Более подробно методы хранимых классов будут рассмотрены ниже.
10.2.2 Работа с классами
Классы
Для того, чтобы определить класс (создать спецификацию класса) необходимо определить элементы его спецификации, перечисленные ниже:
- имя класса
- параметры
- свойства
- методы
- запросы
- индексы
- триггеры
Необычность списка в том, что добавлены запросы и триггеры, а индексы представляются элементами в составе класса, неотделимыми от него.
Уникальное имя класса, свойства (атрибуты) и методы понимаются в обычном для ООП смысле. Другие элементы:
- Параметры. Позволяют изменить возможности класса во время его компиляции. При этом обычно используют генераторы методов.
- Запросы — это операции с объектами класса, играющие роль фильтров.
- Индексы. Эти не обычные для ООП элементы используются, как и в реляционной модели, для ускорения доступа.
- Триггеры. Определяются в рамках объектной модели, так как в действительности и для таблиц, и для классов создаётся единственная структура. Используются триггеры только в реляционной модели, так как активность в объектной модели реализуется методами классов.
Свойства
Свойства представляют собой константы предопределенных типов, ссылки на объекты, встроенные объекты, потоки данных (BLOB, CLOB), коллекции, древесные значения и отношения. Коллекции могут быть массивами и списками.
Несколько примеров задания свойств:
-
Переменная строчного типа
Property Name As %String(MAXLEN = 20);
-
Ссылка на объект. Пусть имеется хранимый класс Address. Тогда свойство Address можно описать так
Property Address As Address;
-
Встроенный объект. Пусть имеется встраиваемый класс Address. Свойство Address записывается точно так же как в предыдущем варианте
Property Address As Address;
но речь идет не о ссылке, а о встраивании объекта.
Свойства-отношения используются и в расширенной реляционной модели, и в объектной. Для независимых объектов поддерживается тип один-ко-многим, а для зависимых родитель-потомок (потомок зависит от родителя). Отношение подобно свойству содержащему две объектные ссылки. При этом обеспечены ссылочная целостность. В результате, при удалении объекта не может появиться висячая ссылка на другой стороне отношения. На одной стороне отношения (многие или потомок) помещается как бы простое свойство, а на другой стороне коллекция, наследующая системному классу %RelationshipObject.
В определении класса Cache можно задать вариант хранения свойств, указывая одно из ключевых слов transient, calculated, multidimensional. Задание по умолчанию определяет свойство, которое имеется в памяти и хранится в базе данных.
Если свойство объявлено временным (transient), то при сохранении экземпляра класса оно не заносится в базу. Такие свойства позволяют создавать промежуточные значения, связанные с классом. Локальные переменные такой связи обеспечить не могут.
Если свойство объявлено как вычисляемое (calculated), то его значения будут вычисляться каждый раз при выполнении. Для свойств этого вида разработчик должен сам создать метод Get() производящий необходимые вычисления.
Ключевое слово multidimensional означает, что свойство представляет многомерный массив.
Коллекции можно рассматривать как отношения .
Методы
Как всегда в ООП, различают метод класса и метод экземпляра (объекта). Метод класса не имеет доступа к свойствам или методам экземпляров, однако имеет доступ к параметрам классов. Типичный пример метода класса — конструктор %New(), который не применим к экземпляру класса, но порождает его.
В коде метода можно определить язык, на котором метод написан. Тексты на языках ObjectScript и Cache Basic транслируются в исполняемый код. Методы написанные на Java выполняются в среде виртуальной машины Java.
Методы могут возвращать данные любого допустимого типа.
Методы работают с данными, получаемыми через их аргументы. Количество аргументов любое. Существуют методы без аргументов. При определении метода задаются имена аргументов и их типы. Если аргумент представляет ссылку, то его имя начинается с символа амперсанд ("&") и возможно изменение значения переменной аргумента во время выполнения метода. Другие аргументы во время выполнения метода меняться не могут.
Cache поддерживает четыре типа методов:
- Методы-коды (Code Methods);
- Методы-выражения (Expression Methods);
- Методы-вызовы (Call Methods);
- Методы-генераторы (Method Generators).
Метод-код представляет собой программу, написанную на языках Object-Script, Cache Basic или Java. При использовании первых двух языков в код метода можно включать макросы, встроенный SQL, встроенные HTML и JavaScript.
Метод-выражение содержит одно вычисляемое выражение, после своего вызова вычисляет его и возвращает результат.
Метод-вызов обращается к внешней для класса программе.
Метод-генератор содержит код, предназначенный для порождения кода на языке ObjectScript. Используется только при компиляции класса для генерации версии времени исполнения.