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

       

Путевые выражения


Для навигации между подобъектами сложных объектов и по связям между разными объектами в OQL поддерживается специальный вид выражений, называемых путевыми (path expression ). Эти выражения определяются в так называемой точечной нотации (вместо операции “.” можно использовать и операцию “->”). Рассмотрим несколько простых примеров. Предположим, что в классах DEPT и EMP , кроме связи CONSISTS _ OF - WORKS определена еще и связь “один-к-одному” MANAGED _ BY - MANAGER _ OF :

class DEPT {

...
relationship EMP managed_by
inverse EMP :: manager_of
... }

class EMP {

...
relationship DEPT manager_of
inverse DEPT :: managed_by
... }

Пример 2.7. Для получения объекта типа EMP , соответствующего менеджеру отдела main _ department достаточно написать выражение

main_department.managed_by

Если же требуется получить имя менеджера отдела main _ department , то можно воспользоваться путевым выражением

main_department.managed_by.EMP_NAME

Пример 2.8. Получить имена всех сотрудников отдела main _ department.

Кажется, что запрос очень похож на предыдущий, и что для него годится выражение

main_department.consists_of.EMP_NAME

Но в данном случае мы имеем связь “один-ко-многим”, и хотя у каждого служащего имеется только одно имя, такие путевые выражения в OQL не допускаются. Правильной формулировкой запроса является следующая:



SELECT E.EMP_NAME
     FROM main_department.consists_of AS E

Предикаты и логические операции

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

Пример 2.9. Получить номера отделов и имена сотрудников отделов, с размером зарплаты, большим 10000 руб., работающих в отделах с числом сотрудников, большим 40 человек, и со средним размером зарплаты, большим 20000 руб.

SELECT STRUCT (DEPT_NO : D.DEPT_NO, EMP_NAME : E.EMP_NAME )

     FROM DEPARTMENTS D,

          D.CONSISTS_OF E


     WHERE D.DEPT_EMP_NO > 40 AND
           AVG (E.EMP_SAL) > 20000.00 AND

           E.EMP_SAL > 10000.00

Как следует понимать семантику выполнения данного запроса? Образуется внешний цикл по просмотру объектов экстента DEPARTMENTS . Для каждого из этих объектов по связи CONSISTS _ OF образуется коллекция (в данном случае, множество) объектов, входящих в экстент EMPLOYEES . Тем самым, выполняется неявная факторизация (группирование) экстента EMPLOYEES , в которой инвариантом группы служащих является их общий отдел. По этому поводу в списке выборки и в условии выборки (предикате) разрешается использовать как свойства инварианта группы (в нашем случае, DEPT . DEPT _ NO и DEPT . DEPT _ EMP _ NO ) и индивидуальные свойства членов групп (в нашем случае, EMP . EMP _ NAME и EMP . EMP _ SAL ), так и “агрегатные” свойства группы в целом (в нашем случае, AVG ( EMP . EMP _ SAL ) ). Для каждой группы, образуемой во внешнем цикле, оцениваются условия, характеризующие группу в целом. В просмотр внутреннего цикла допускаются только те группы, для которых результатом вычисления условий “группы” было true . За каждым элементом “отобранной” группы сохраняются свойства ее объекта-инварианта.

Как видно даже из этого примера, предикаты раздела WHERE OQL -запросов могут представлять собой произвольно сложное булевское выражение, в котором простые условия связываются логическими операциями AND, OR и NOT. Очевидно, что этот набор операций является избыточным. Тем не менее, в OQL введены две дополнительные логические операции – ANDTHEN и ORELSE . Если X и Y являются логическими выражениями, то при вычислении выражения X ANDTHEN Y выражение Y вычисляется (и определяет общий результат) в том и только в том случае, когда результатом вычисления выражения X является true . Аналогично, при вычислении выражения X ORELSE Y выражение Y вычисляется (и определяет общий результат) в том и только в том случае, когда результатом вычисления выражения X является false . Другими словами, таблицы истинности операций ANDTHEN и ORELSE полностью совпадают с таблицами истинности операций AND и OR соответственно, но предписывается порядок вычислений.


Стандарт ODMG 3. 0 не обеспечивает подробного обоснования для введения этих операций, однако, по нашему мнению, это как-то связано с желанием остаться в рамках двухзначной логики при возможности наличия неопределенных значений. Вот пример запроса, в предикате которого можно сравнительно осмысленно использовать операцию ANDTHEN .

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

SELECT STRUCT (name: E.EMP_NAME, dept: D.DEPT_NO)
     FROM EMPLOYEES E,

E.WORKS D

     WHERE E.WORKS != nil andthen

   D.DEPT_TOTAL_SAL > 1000000.00

38

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

Пример 2.10. Выбрать всех служащих, у которых имеются однофамильцы.

SELECT DISTINCT E
     FROM EMPLOYEES E, EMPLOYEES E1
     WHERE E != E1 AND E.EMP_NAME = E1.EMP_NAME

В результате будет образовано литеральное множество, элементами которого являются объекты типа EMP , для которых в экстенте EMPLOYEES имеется хотя бы один иной (с другим объектным идентификатором) объект, с тем же значением свойства EMP _ NAME . Понятно, что этот запрос и по виду, и по семантике выполнения является в чистом виде SQL -запросом (если заменить конструкцию E != E1 наE.EMP_NO <> E1.EMP_NO ).


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