СТАТЬЯ 30.07.01

Обзор объектно-ориентированной СУБД Jasmine

Предыдущая часть

Александр Зашихин,
Computer Associates
Cтатья была опубликована на сайте www.citforum.ru

3.2. Методы

Петер Коуд (Peter Coad) "Объектные модели. Стратегии, шаблоны и приложения" считает, что каждый объект должен отвечать на три вопроса: "что он знает?", "что он видит?", "что он может делать?". Так вот:

Примерно так же считают Эдвард Йордон (Edward Yourdon) и Карл Аргила (Carl Argila).

Метод - это действие, которое может выполнить тот или иной объект. Такими объектами могут быть:

В соответствии с этим и методы могут быть:

  1. Уровня экземпляра, это когда метод может быть вызван любым, но только одним экземпляром в классе.
  2. Уровня коллекции экземпляров, это когда метод может быть вызван некоторой коллекцией экземпляров в классе.
  3. Уровня класса, это когда метод может быть вызван классом в целом.
  4. Уровня коллекции классов, это когда метод может быть вызван некоторой коллекцией классов.

Физически метод - это код, реализующий некоторый алгоритм (сейчас говорят - алгоритм некоторого бизнес-процесса), выполненный на одном из алгоритмических языков, называемых базовым, с включением кода на языке запросов в базу данных и позволяющий не только добавлять, удалять, корректировать и получать данные, но и создавать новые классы, свойства и т.д., т.е. изменять существующую систему (речь идет об эволюции системы).

Технология создания метода проста. Сначала, с использованием некоторого базового языка и языка запросов в базу данных, пишется код (любым текстовым редактором), реализующий алгоритм некоторого бизнес-процесса. Затем этот код средствами Jasmine Method Editor (о нем мы будем говорить позже) оформляется (речь идет о компиляции) в виде метода и добавляется в один из классов. Надо сказать, что алгоритм бизнес-процесса может и не содержать запросов в базу данных, а может быть только запросом в базу данных.

В качестве базового языка можно использовать C/C++ или Java, а для запросов в объектную базу данных можно использовать только ODQL (Object Database Query Language - язык запросов в объектную базу данных).

Поскольку методы являются частью объектов, то они всегда находятся там же, где и объекты, - в базе данных, а значит выполняются на сервере, т.е. быстро и с полным набором всех средств защиты и операционной системы и СУБД. Таким образом, при использовании методов, клиент всегда "тонкий" и, как мы узнаем дальше, его можно еще "утоньшить". Сторонники реляционных баз данных спросят: "А чем хранимая процедура выбора или выполнения (т.е. откомпилированный код SQL, хранящийся в базе данных, а значит выполняющийся на сервере), обеспечивающая "тонкого" клиента, хуже?" Основное отличие методов от хранимых процедур заключается в том, что методы наследуются!

Транзакции можно начинать, заканчивать, или откатывать назад из приложения, но не из методов! Отсюда вытекает основное требование: методы должны быть не интерактивными и по возможности короткими!

Существует два способа использования методов:

  1. Метод можно использовать в качестве действия при задании поведения элемента сцены.
  2. Метод можно использовать в запросе, делая так называемый вызов метода. Запрос же, в свою очередь, может быть элементом сцены с вытекающими отсюда последствиями (пояснить).

3.3. ODQL и запросы

Давайте вспомним, почему SQL встраивался в алгоритмический язык? Да потому, что в нем не было основного: возможности объявления переменных и условных операторов. В ODQL все это есть, т.е. можно и объявлять переменные, и использовать условные операторы (инструкции) if-else, while, scan, indexScan.

Переменные можно объявлять следующим образом:


1. Integer I;

    String S;

    Decimal[8,2] D;

    где переменные I, S и D - соответственно целое число, символьная строка и десятичное

    число.

2. Bag BI;

    Bag BS;

    где переменные BI и BS - соответственно коллекция (набор) целых чисел и коллекция

    символьных строк.

3. Manager M; 

    где переменная M - экземпляр класса Manager.

    На языке С это могло бы выглядеть как-то так:

    struct Manager
        {
           int ABC;
           float CDE;
            . . .
           char name[10];
        };

4. Bag BM;

    где переменная BM - коллекция экземпляров класса Manager.

5. Manager class MC;

    где переменная MC - класс Manager и любой из его подклассов, если далее это

    специально не оговаривается.

6. Bag BMC;

    где переменная BMC - коллекция классов из числа подчиненных классу

    Manager, включая класс Manager.

7. [Integer I, String S, Decimal[8,2]] ISD;

    где переменная ISD - кортеж (коллекция свойств экземпляра в классе).

8. Bag<[Integer I, String S, Decimal[8,2 BISD;

    где переменная BISD - коллекция кортежей.

Если инструкции if-else, while обычны, то инструкция scan (ABC, A) { . . . }; означает: для каждой переменной A из коллекции ABC (а коллекции, мы уже знаем, могут состоять из кортежей, классов, экземпляров класса, значений свойств) надо выполнять действия, указанные в фигурных скобках. Есть готовый метод createIterator( ), называемый итератором и дающий более гибкие возможности по сравнению с инструкцией scan, т.к. он позволяет обрабатывать коллекцию в обоих направлениях, но при этом необходимо использовать еще два готовых метода advance( ) и get( ). Необходимо отметить, что можно иметь много активных итераторов одновременно. Кроме того, Вы можете создать и собственный метод итерации.

Код практически любого бизнес-процесса можно полностью написать на ODQL, т.е без использования инструкций базового языка! Однако ODQL, являясь интерпретатором, все равно встраивается в базовый язык.

Если Вы используете базовый язык с языком запросов в базу данных, то инструкции ODQL, встраиваемые в базовый язык обязательно должны начинаться со знака $, что отличает их от инструкций базового языка. К переменным ODQL необходимо обращаться из инструкций ODQL, к переменным базового языка необходимо обращаться из инструкций базового языка. Но ODQL настолько хорошо интегрирован с C/C++, что в инструкциях C/C++ можно использовать переменные ODQL ! Надо только не забывать, что для этого:

  1. При объявлении ODQL-переменных, каждой ODQL-переменной должны соответствовать две переменных базового языка, например: $Integer A <Aval, Astat>; т.е. переменной A целого типа языка ODQL соответствуют две переменные языка С/С++ - переменная значения Aval и переменная состояния Astat.
  2. При чтении переменной ODQL в инструкции базового языка сначала необходимо проверить переменную состояния, а затем уже читать переменную значения.
  3. При записи переменной ODQL в инструкции базового языка сначала необходимо установить переменную значения, а затем - переменную состояния.

Говорить о возможности использования библиотечных функций C/C++ как базового языка наверно нет необходимости.

Существует два способа создания запросов :

  1. На языке ODQL пишется код (любым текстовым редактором), реализующий алгоритм некоторого запроса в базу данных. Затем этот код средствами Method Editor оформляется (речь идет о компиляции) в виде метода и добавляется в один из классов.
  2. Запрос можно полностью создать без записи кода (включая отладку) в окне Query Editor. В этом случае запрос является самостоятельным объектом, который может быть "отбуксирован" на сцену. Запрос извлекает экземпляры из классов целиком! Его классовую принадлежность можно увидеть в закладке Queries в правой части окна Class Browser (разъяснить заблуждение по поводу слабости запросов ODQL).

Запрос всегда обращается ко всем подклассам класса, если не используется ключевое слово alone во from-спецификации запроса.

Существует два способа использования запросов:

  1. Запрос, если это метод, можно использовать в качестве действия при задании поведения элемента сцены (уже известно).
  2. Запрос, если он создан средствами Query Editor, можно использовать в качестве элемента сцены.

(Разъяснить заблуждение по поводу того, что ODQL - только для запросов, а C/C++ - для мощных вычислений. Сравнить листинги запросов на SQL и ODQL).

3.4. Объектные идентификаторы и указатели в памяти

В объектных базах данных по сравнению с реляционными имеется два источника повышения производительности:

  1. Объектные идентификаторы, при обращениии к объектам в базе данных;
  2. Указатели, при обращении к объектам в оперативной памяти.

Объектный идентификатор (OId - Object Identifier) - это нечто, уникально идентифицирующее объект в базе данных. Если OId является физическим адресом объекта, то выборка объекта из базы данных осуществляется по этому физическому адресу, если - логическим адресом, то выборка объекта осуществляется по адресу, взятому из хэш-таблицы, преобразующей (отображающей) логические адреса объектных идентификаторов в их физические адреса.

Сторонники реляционных баз данных утверждают, что в скорости выборки информации реляционные базы данных не уступают объектным. Оставим это на их совести.

Указатель. После того как объект извлечен из базы данных и загружен в оперативную память, его OId конвертируется в указатель. Таким образом указатель - это адрес объекта но уже в оперативной памяти. Перемещение от объекта к объекту по указателям в оперативной памяти называется навигацией и теперь уже сторонники объектных баз данных утверждают, что именно она повышает производительность объектной базы данных по сравнению с реляционной на 2-3 порядка! При этом они ссылаются на базы данных в оперативной памяти, так называемые MMDb (Main Memory Database).

Кто же прав? Дело в том, что в объектных базах данных при выборке не принято отображать информацию до полного заполнения последнего из элементов изображений. Поэтому, при внешне одинаковой реактивности реляционной и объектной систем, в объектной базе данных скорость выборки должна быть на 2-3 порядка выше. Можете ли Вы представить, что храните в реляционной базе данных и выбираете из нее в качестве свойства например, коллекцию *. JPG файлов?! BLOb здесь бессилен!

Индексация в объектных базах данных тоже повышает производительность системы, но она не так важна, как в реляционных, поскольку в объектных есть навигация. Индексы могут быть в любой момент созданы методом createIndex( ) и удалены методом dropIndex( ). CA рекомендует не использовать индексы там, где возможны частые корректировки. Эксплуатируют индексы с помощью ранее упомянутой инструкции indexScan языка ODQL, особенностью которой является возможность задания диапазона сканирования и то, что она может применяться только к конкретному классу без его подклассов.

Не надо забывать, что эволюция любой системы влечет за собой усложнение отношений между классами, а значит - увеличение числа свойств-связей, а значит - числа OId. Но чем больше указателей при загрузке объектов в оперативную память, тем выше производительность системы. Другой вопрос: "А сколько нужно этой самой оперативной памяти?". Как бы там ни было, но пока быстродействие и объем оперативной памяти растут, будет расти и производительность объектных баз данных!, поскольку именно они имеют OId и указатели в памяти.

Продолжение статьи

Дополнительную информацию Вы можете получить в компании Interface Ltd.

Отправить ссылку на страницу по e-mail
Обсудить на форуме Computer Associates


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован: 30.07.01