Реализация навигационного языка для объектных баз данных на основе SQL-сервера oracle

Реализованы два режима работы программы: режим настройки и режим обработки потока исходных данных.

В режиме настройки пользователь создает конструкт-объекты (Определители, Рекомендации, Виртуальные Датчики, Правила Слежения) и настраивает их свойства.

В режиме обработки потока исходных данных пользователь задает поток исходных данных и получает доступ к аналитическим выводам программы, в частности:

♦ к смысловым определениям показаний датчиков;

♦ к диаграммам истории показаний любого из виртуального датчиков;

♦ к рекомендациям по соответствующим показаниям виртуальных датчиков;

♦ а также к экранным индикаторам состояния той или иной части контролируемой системы, всей системы в целом.

Поток исходных данных состоит из цифровых значений показаний аппаратных датчиков (в формате Extended), отображающих состояние объектов наблюдаемой системы. Исходные данные, поступающие от аппаратного датчика, записываются в Свойство Indication(показание) виртуальных датчиков.

Средой функционирования программы Recommenator является операционная система типа Windows 95,98,NT. Для создания программы применялась интегрированная среда разработки приложений Delphi 3.0.

УДК 681.3.016

Д.А.Заставной

РЕАЛИЗАЦИЯ НАВИГАЦИОННОГО ЯЗЫКА ДЛЯ ОБЪЕКТНЫХ БАЗ ДАННЫХ НА ОСНОВЕ SQL-СЕРВЕРА ORACLE

1. Введение

Современные приложения, такие как системы автоматизированного проектирования, так же как и традиционные системы применения баз данных, требуют наличия инструментальных средств, поддерживающих моделирование и оперирование с данными сложной структуры. Такие данные, образующиеся совокупностью объектов (сущностей) и связей между ними, удобно хранить в объектной базе данных. Для извлечения данных из ОБД используются высокоуровневые языки запросов, которые позволяют специфицировать множества данных. Основные существующие системы ОБД (ODMG, SQL3) [3,4], однако, обладают, по мнению автора, некоторыми недостатками, главный из которых, с концептуальной точки зрения, - недостаточная выразительность средств оперирования с совокупностями связанных объектов.

Автор развивает собственный язык запросов для ОДБ [1,2], позволяющий специфицировать множества путей в ОДБ, состоящих из объектов, связанных различными семантическими связями. Средства этого языка, позволяющие иден-

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

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

Данная работа описывает основные аспекты реализации языка запросов для ОБД и подъязыка доступа к компонентам значений запросов.

2. Навигационный язык запросов и язык вторичной навигации

Основной особенностью приложенного языка запросов [1,2] является возможность специфицирования и извлечения из объектной базы данных множеств связанных объектов - так называемых элементарных путей в ОДБ. Элементарный путь представляет собой множество объектов, попарно связанных между собой именованными семантическими связями. Запрос к БД формально специфицирует множество таких путей, используя выражения, которые образуются операторами навигации, фильтрации по именам и другим условиям на объекты получения значений полей (атрибутов) объектов и т.д. В состав выражений входят имена типов объектов, имена связей, полей и имена объектов. Ниже приведен пример запроса, взятого из [1], извлекающего из ОБД информацию о студентах, посещения ими курсов по базам данных и логике, и аудиториях, закрепленных за указанными курсами в расписании.

STUD. attends / {Databases, Logic} .at.' reservedJor

В данном примере использованы операторы навигации (“.”) и оператор фильтрации по именам (“/”). Значением данного запроса, согласно [1], являются три элементарных пути:

{ STUD/Bill °attends/Databases ° TIMETABLE/* °'reservedJor /В08.

STUD/Jane °attends/Databases ° TIMETABLE/* °'reservedJor/В08,

STUD/Jane ° attends/Logic ° TIMETABLE/* ° 'reserved Jor /В08 } .

Каждый элементарный путь включает 4 уровня объектов и соответственно три экземпляра связей между объектами уровней. Очевидно, структура путей является сложной, и все объекты каждого уровня путей представляются отдельным результирующим множеством. На рисунке показана структура значения запроса.

STUD COURSE TIMETABLE ROOM

Bill

Jane

Двумя важными особенностями способа представления значения является, во-первых, то, что каждый объект хранится в кеше в одном экземпляре, и, во-вторых, сохраняются экземпляры связей между объектами в кеше.

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

В функции подъязыка доступа к значениям запросов входят операции позиционирования текущей записи в результирующем множестве и извлечение данных из текущей записи. Позиционирование осуществляется командой

SET { FIRST I NEXT | PREV }.

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

Локальная рекомпозиция осуществляется командой

SET { LEFT I RIGHT } { FIRST | NEXT | PREV } „

Данная команда требует, чтобы какое-либо результирующее множество было сделано текущим для просмотра.

Полная рекомпозиция реализуется при помощи команды

SET PATH { FIRST | NEXT | PREV }.

3. Архитектура системы

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

Типичная работы с интерпретатором включает следующие шаги:

1. Исполнение запроса.

2. Позиционирование текущих элементов в результирующих множествах.

3. Извлечение данных.

Основные функциональные составляющие системы:

- сканер, читающий входной поток и выполняющий преобразование считанных команд во внутреннее представление;

- менеджер результирующих множеств кеша, управляющий созданием, инициализацией и манипулированием ими;

- ядро СУБД, обеспечивающее физическое извлечение данных из БД, размещение их в результирующих множествах и доступ к этим данным.

Ядро использует в качестве низкоуровневого репозитория данных SQL-сервер Огас1е7, который обеспечивает управление данными на нижнем уровне. В его основные задачи входят: представление и хранение объектов (в т.ч. значений полей каждого экземпляра) и экземпляров связей при помощи структур реляционной БД, извлечение этих данных при исполнении выражений языка запросов, моделирование результирующих множеств и помещение и извлечение из них данных.

Таким образом, система-интерпретатор с точки зрения реализации является надстройкой над SQL-сервером, однако, с концептуальной точки зрения, наша система не зависит от SQL, и предложенный язык не является каким-либо его расширением.

4. Реализация на основе SQL-cepeepa

Реализуемая система является надстройкой над SQL-сервером, и все операции по физическому сохранению и извлечению данных реализуются при помощи генерации и исполнения команд SQL. Средства SQL-сервера решают следующие функциональные задачи:

1. Хранение экземпляров объектов и связей.

2. Извлечение объектов при исполнении запросов первичной навигации.

3. Хранение результирующих множеств кеша.

4. Доступ к компонентам результирующих множеств.

Таким образом, основой реализации системы является трансляция языковых конструкций языка запросов в операторы SQL. В данном разделе описываются основные методы для решения перечисленных выше задач.

4.1.Хранение экземпляров объектов и связей

Множество экземпляров каждого типа в реляционной БД представляется таблицами, создаваемыми при определении (декларации) данного типа соответствующей командой языка (CREATE TYPE, см. [2]). Эти таблицы содержат имя

объекта, внутренний идентификатор и знамения полей. Генерация SQL-команд для создание типа <имя_типа> осуществляется по следующему шаблону:

CREATE TABLE <u-w?_ma«a>_STRUCT

(Name char(20), ID integer. <none{> <munj>, ... , <имя^> <munn>).

Экземпляры связей также представлены таблицей, содержащей идентификаторы связанных объектов. SQL-команда, генерирующее представление экземпляров некоей связи <связь> типа <ппт_связи>, определенной в ттге<тип>, порождается в соответствии со следующем шаблоном:

CREATE TABLE <связь>_<тт>_<тип_связи> (id 1 integer, in2 integer).

4.2.Извлечение объектов при исполнении запросов Опишем способ исполнения запросов на основе генерации и исполнения SQL-команд, для запросов так называемых линейных цепочек, содержащих операторы прямой навигации, получения значений полей и фильтрации по именам. В данной работе мы не приводим полного формального определения семантики всех операторов, включая такие аспекты, как проверка и разрешение типов (type resolution), проверка корректности выражений и т.д., отсылая к другим работам [1,2], однако сформулирует основные правила генерации SQL-команд.

Любое линейное выражение вида Т*С,*С2* ...Сп, где * - любой допустимый оператор, предварительно преобразуется в эквивалентное выражение вида T0Ci'0C2'0 ... °Ck', где Cj' - подвыражение, 0 - оператор навигации. Каждое из этих выражение может содержать операторы фильтрации по именам и получения значений полей, но не содержит операции навигации.

Выражение ToCI'0C2,o...oCk' вычисляется как композиция (...(((Co)0Ci')0C2')0 --)0Ck' следующим способом. Сначала вычисляется звено С0, формируя результирующее множество К0. Затем вычисляется значение подвыражения °С1', используя объекты результирующего множества К0 как левый аргумент операции, сформировав новое результирующее множество Ki, и т.д. для каждого 0Cj' на базе результирующего множества Kj.j, вычисленного на предыдущем шаге. По окончанию процесса будет сформирована группа результирующих множеств Кп К, Кг... Кк.

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

Теперь рассмотрим генерацию SQL-команд на j-шаге алгоритма. В общем случае звено С/ может иметь вид:

<имя_евязи> "/"<список_имен_объекггов>" <спнсок_нмен_полей>.

Будем предполагать, что <PMj.i> и <РЩ> - имена соответственно предыдущего и текущего результирующих множеств . Тогда порождаемые SQL-команды имеют следующий вид:

INSERT INTO <PMj>

SELECT Id, Id2, Name, <список_имен_полей>

FROM <PMH>, <имя_связи>_<тигі>_<тип_связи>,

<тип_связи>_ STRUCT WHERE <PMj.i>Ad = <имя_связи>_<muri><тип_связи> .idl

AND <имя_связи>_<т uri>_<m ип_связи>. і d2 =

</WM/7_ca«3u>_STRUCT.id

AND Name in

Команда использует три таблицы: <РМу\> из предыдущего контекста, из которого берутся идентификаторы объектов, затем по этим идентификаторам извлекаются идентификаторы связанных объектов, используя таблицу

<имя_связи>_<тип>_<тип_связи> со значениями экземпляров данной связей, и, наконец, извлекаются имена объектов и значения полей из таблицы <тип_связи>_STRUCT (ограничиваясь объектами с заданными в тексте запроса именами) и помещают их в <PMj>.

Обратим внимание на то, что в результирующих множествах каждая запись однозначно идентифицируется парой (id,id2), соответствующей экземпляру связи.

4.3. Реализация операторов доступа к контекстам

Таким образом, после выполнения запроса образуется набор множеств <PMj>. Доступ к ним осуществляется путем позиционирования текущего элемента и покомпонентного перебора элементов (записей) результирующих множеств. Рассмотрим реализацию операций доступа к результирующим множествам.

Напомним, что каждое результирующее множество реализовано как временная таблица SQL-сервера, а доступ к ним осуществляется через текущие элементы (записи) множеств. Каждому текущему элементы соответствует системный буфер, в котором физически располагаются данные, помещаемые из результирующего множества, - имя объекта и значения его полей. Эти буфера доступны для чтения из них данных приложениями. Выполнение команд группы SET (1), (2), (3) приводит к физическому заполнению буферов данными из результирующих множеств.

Позиционирование текущего элемента в множестве <PMj>, выполняемой командой SET FIRST, осуществляется исполнением SQL-запроса

SELECT Id, Id2, Name, <список_имен_полей> FROM <PMj>

и помещением первого элемента значения SQL-запроса в буфер; для этого используются вызовы функций библиотеки ОСІ [5], выходящей в Огасіе7 и используемой для работы с SQL-запросами из среды языка С. Выполнение команд SET NEXT и SET PREV помещает в буфер соответственно следующую и предыдущую записи выборки для SQL-запроса (4).

Локальная рекомпозиция путей, инициируемая командой SET LEFT FIRST, относительно текущего элемента текущего результирующего множества, реализована исполнением следующей SQL-команды:

SELECT <PMj.!>.Id, <PMj.i>.Id2, <PMj.i>.Name, <список_имен_полей> FROM <PMj.|>, <PM,>

WHERE <PMj.,>.Idl = <PMj.)>.Id2 .

Данная выборка извлекает из <PMj.i> только записи для объектов, которые связаны с объектами из <PMj>, и помещает данные первой записи из него в буфер для результирующего множества <PMj.i>. Выполнения команд SET LEFT {NEXT I PREV} помещают соответственные элементы в буфер.

Наконец, рассмотрим реализацию команд полной рекомпозиции SET PATH, выполнение которых генерирует все пути, порожденные исходным запросом; вычисление каждого пути приводит к автоматическому установлению текущих элементов в каждом результирующем множестве. При исполнении команды SET PATH FIRST в первом результирующем множестве выставляется первый текущий элемент, а затем в остальных результирующих множествах последовательно (для второго, третьего и т.д. до последнего) выполняется автоматическая частичная рекомпозиция путей согласно описанной выше технике. Выполнение команд SET PATH { NEXT | PREV } вызывает переустановку текущего элемента на следующую запись в последней выборке; если выборка исчерпана, происходит переустановка текущего элемента на следующий на предыдущем результирующем множестве и повторная частичная рекомпозиция для последнего результирующего множества. Данный процесс повторяется, пока не будут исчерпаны все возможности новых частичных рекомпозиций для всех результирующих множеств, включая первое. Описанная процедура реализует обход множества путей в графе по принципу «сверху вниз слева направо».

ЛИТЕРАТУРА

1. Заставной Д.А. Спецификация и представление сложных навигационных запросов для объектных баз данных. //'Материалы Всероссийской конференции "Компьютерные технологии в инженерной и управленческой деятельности", Таганрог, Издательство ТРТУ, 1999.

?.. Bukatov A., Zasiamoy D. High-level Navigational Language for Querying Complex Data Objects and its Application to CASE Systems. //Proceeding of Second Joint Conference on Knowledge-Based Software Engineering. IOS Press. Amsterdam. 1998.

3. Cattell R.G.G, Barry D.K. (ed) “The Object Database Standart: ODMG 2.0”. Morgan Kaufmann publ. San Francisco, 1997.

4. ЭнсорД. Oracle8: рекомендации разработчикам. Киев. BHV. 1998.

5. Oracle7 Application Developer’s Guide. Oracle Corp. 1997.