Скачиваний:
79
Добавлен:
02.05.2014
Размер:
2.54 Mб
Скачать

22.8. Реляционные операторы для обработки интервалов

Скалярные операторы для обработки интервалов, описанные в разделе 22.6, ко­нечно, могут использоваться и в скалярных выражениях, которые, в свою очередь, могут применяться в соответствующих местах реляционных выражений. В языке Tutorial D, например, к таким местам относятся в основном предложения WHERE в операторах выборки и предложения ADD в операторах EXTEND и SUMMARIZE. Так, на­пример, запрос "Определить номера поставщиков, которые могут поставить деталь с номером 'Р2' в день 8" для базы данных, представленной на рис. 22.4, можно выра­зить следующим образом.

( SP_DURING WHERE Pi = Р# ('Р2') AND d08 IN DURING ) { Si }

Замечание. На практике выражение d08 было бы заменено соответствующим литера­лом типа DAY.

В качестве другого примера рассмотрим выражение, с помощью которого можно получить отношение, показывающее пары поставщиков, находящихся в одном и том же городе в одно и то же время, вместе с названиями городов и соот­ветствующими датами.

EXTEND

{ ( { ( S DURING RENAME Si AS XS#,

DURING AS XD ) { XSi, CITY, XD }

JOIN

( S_DURING RENAME Si AS YSi,

DURING AS YD ) { YSi, CITY, YD } ) WHERE XD OVERLAPS YD ) ADD ( XD INTERSECT YD ) AS DURING ) { XSi, YSi, CITY, DURING }

Пояснения. С помощью оператора JOIN выполняется поиск пар поставщиков, которые находятся в одном и том же городе. Предложение WHERE ограничивает ре­зультат парами, которые находились в одном и том же городе в одно и то же вре­мя. Предложения EXTEND ... ADD используются для вычисления соответствующих интервалов. И в конце концов с помощью операции проекции получается желае­мый результат.

Теперь возвратимся к запросам 3.1 и 3.2 из раздела 22.3. Сначала рассмотрим за­прос 3.1. В новой формулировке обозначим его как запрос 4.1. Для базы данных, пред­ставленной на рис. 22.4, он будет звучать следующим образом.

Запрос 4.1. Получить пары атрибутов Si, DURING для поставщиков, которые могут поставить некоторую деталь в некоторое время, где атрибут DURING означает пе­риод максимальной продолжительности, в течение которого поставщик с номером Si действительно мог поставить некоторую деталь.

Напомним, что в ранней версии этого запроса (запрос 2.1) необходимо было использовать группирование и обобщение, а именно — обращаться к операции SUMMARIZE. Поэтому неудивительно, что для формулировки запроса 4.1 также нужны определенные операции группирования и обобщения. Однако в данном случае мы будем формулировать требуемый запрос не сразу, а поэтапно. Первый этап представлен ниже.

WITH SP_DURING { Si, DURING } AS Tl :

(Двоеточие указывает, что существует продолжение этого выражения.) На данном этапе в исходном отношении SP_DURING просто отбрасываются номера деталей. Резуль­тирующее отношение Т1 имеет следующий вид.

s#

DURING

SI

[d04,dl0]

SI

[d05,dl0]

SI

[d09,dl0]

SI

[d06,dl0]

S2

[d02.d04]

S2

[dOS,dOS\

S2

[d08,dl0]

S2

[d09,dlO]

S3

[dOS.dlO]

S4

[d06,d09]

S4

[d04,d08]

S4

[dOS.dlO]

Отметим, что в этом отношении содержатся избыточные данные. Например, излишне трижды говорить о том, что поставщик с номером 'S1' может что-то поставить в день 6. Поэтому требуемое отношение, назовем его RESULT, в котором уже нет подобной избы­точности, будет таким.

s#

DURING

si

[d04,dl0]

S2

[d02,d04]

S2

[d08,dl0\

S3

[dOS.dlO]

S4

[d04,dl0]

Назовем этот результат свернутой формой отношения Т1 по атрибуту DURING. Под­черкнем, что значение атрибута DURING для данного поставщика в этой свернутой форме необязательно должно быть представлено как явное значение атрибута DURING для данного поставщика в отношении Т1, производной от которого является данная свернутая форма. В нашем примере это замечание относится, в частности, к поставщику с номером ' S4'.

Может показаться, что достичь такого состояния совсем несложно, получив эту свер­нутую форму с помощью простого выражения следующего вида.

Tl COALESCE DURING

Однако к данной цели необходимо продвигаться постепенно.

Прежде всего обратите внимание, что термин "свернутая форма" в двух предыдущих абзацах использовался в смысле, который несколько отличается от того, который вкла­дывался в это понятие в разделе 22.7. Оператор COALESCE, как он был определен в разде­ле 22.7, принимает в качестве входных данных и выдает в качестве выходных данных множество интервалов. Однако здесь рассматривается другая его версия — фактически перегруженная (см. главу 19) версия этого оператора, когда он в качестве входных дан­ных принимает унарное отношение и в качестве выходных данных выдает другое отно­шение с тем же заголовком, причем оба отношения состоят из кортежей, которые содер­жат настоящие интервалы.

Теперь подробнее рассмотрим этапы, которые позволяют перейти от отношения Т1 к отношению RESULT.

WITH ( Tl GROUP ( DURING ) AS X ) AS T2 :

(Напомним, что оператор GROUP подробно рассматривался в главе 6.) Отношение Т1 представлено ниже.

s#

X

SI

DURING

[d04,dl0]

[dOS.dlO]

[d09,dl0]

[d06,dl0]

S2

DURING

[d02,d04]

[d03,d03]

[d08,dl0]

[d09.dl0\

S3

DURING

[d08,dl0]

S4

DURING

[d06,d09]

[d04,d08]

\d05,dW\

Далее применим новую версию оператора COALESCE к отношениям, которые являются значениями атрибута X (его значения имеют тип отношения).

WITH ( EXTEND Т2 COALESCE ( X ) AS Y )

{ ALL BUT X } AS T3 :

Отношение ТЗ выглядит так.

S#

SI

DURING

[d04,dl0]

S2

DURING

[d02,d04] [d08,dl0]

S3

DURING

084101

S4

DURING

\d04,dl0]

Наконец разгруппируем это отношение (опять же, см. главу 6). ТЗ UNGROUP Y

Это выражение служит для получения отношения, которое ранее было названо нами RESULT. Иными словами, объединив все шаги и сделав небольшие упрощения, получим окончательное выражение, которое в результате даст отношение RESULT.

WITH SP_DURING { St, DURING } AS Tl, ( Tl GROUP ( DURING ) AS X ) AS T2,

( EXTEND T2 ADD COALESCE ( X ) AS Y ) { ALL BUT X } AS T3 : T3 UNGROUP Y

Очевидно, было бы лучше, если бы можно было получить результирующее отноше­ние RESULT из отношения Т1 с помощью единственной операции. С этой целью введем новый оператор "реляционного свертывания" со следующим синтаксисом.

R COALESCE А

Здесь R— реляционное выражение, а А— некоторый атрибут некоторого интерваль­ного типа, и этот атрибут принадлежит отношению, которое данное выражение обозна­чает9. Семантика этих операторов определяется очевидными обобщениями операций группирования, расширения, проекции и разгруппирования, с помощью которых было получено отношение RESULT из отношения Tl.

Замечание. Стоит отметить, что свертывание отношения R по атрибуту А предусмат­ривает его группирование по всем атрибутам, кроме атрибута А (напомним, что, как ука­зывалось в главе 6, например выражение Tl GROUP(DURING)... может читаться как "сгруппировать отношение Т1 по атрибуту St", где Si — единственный атрибут отноше­ния Tl, не указанный в предложении GROUP).

Суммируя все сказанное выше, теперь можно предложить более приемлемую и дос­таточно простую формулировку запроса 4.1.

SP_DURING { Si, DURING } COALESCE DURING

В целом, операция, которая обозначается этим выражением, является примером того, что некоторыми авторами называется хронологической проекцией. А точнее, это "хронологическая проекция" отношения SP_DURING по атрибутам Si и DURING. (Напомним, что в первоначальной версии этого запроса (запрос 1.1) использовалась обычная проекция отношения SP по атрибуту Si.) Заметим, что хронологическая проекция — это не совсем проекция как таковая; скорее, это "хронологический аналог" обычной проекции.

Теперь перейдем к запросу 3.2. Исходя из содержимого базы данных, представленно­го на рис. 22.4, этот запрос можно переформулировать следующим образом.

При желании операнд Л мог бы быть расширен, чтобы можно было задать список имен атрибутов. Аналогичное замечание относится также к оператору "реляционного развертыва­ния" (см. ниже). Именно такая семантика приведена в упр. 22.8.


■ Запрос 4.2. Получить пары атрибутов Si, DURING для тех поставщиков, которые не могут поставить ни одной детали в определенное время, где атрибут DURING пред­ставляет максимально продолжительный период, в течение которого поставщик St фактически не мог поставить ни одной детали.

Напомним, что в исходной версии этого запроса (запрос 1.2) использовалась опера­ция получения реляционной разности. Поэтому вы не ошибетесь, если предположите, что в данном случае нам потребуется новая операция, которая будет называться "хро­нологическая разность". Также можно рассчитывать на то, что как "хронологическая проекция" требует "реляционного свертывания", так "хронологическая разность" потре­бует "реляционного развертывания".

Операция получения "хронологической разности", как и обычная операция вы­читания, включает два операнда типа отношений. Сначала рассмотрим левый опе­ранд. Если мы развернем результат обычной проекции S_DURING {Si,DURING} по атрибуту DURING, то получим отношение (скажем, Т1), которое будет выглядеть следующим образом.

s#

DURING

SI

[d04,d04]

SI

[d05,d05]

SI

[d06,d06]

SI

[d07,d07]

SI

[d08,d08]

SI

[d09,d09]

SI

[dlO.dlO]

S2

[d07,d07]

S2

[d08,d08]

S2

[d09,d09]

S2

[dlOMO]

S2

[d02,d02}

S2

[d03,d03]

S2

[d04,d04J

S3

[d03,d03]

При использовании данных, представленных на рис. 22.4, отношение Tl будет содер­жать всего 23 кортежа. (Упражнение. Проверьте достоверность этого утверждения.)

Если определить версию "унарного отношения" для оператора UNFOLD по аналогии с версией "унарного отношения" для оператора COALESCE, то отношение Tl можно будет получить таким образом.

( EXTEND ( S_DURING { S#, DURING } GROUP ( DURING ) AS X ) ADD UNFOLD ( X ) AS Y { ALL BUT X } UNGROUP Y

Однако, как уже указывалось, это выражение можно упростить, если ввести оператор "реляционного развертывания" со следующим синтаксисом.

R UNFOLD А

Теперь можно записать следующее.

WITH ( S_DURING { Si, DURING } UNFOLD DURING ) AS Tl :

Правый операнд "хронологической разности" мы представляем следующим образом.

WITH ( SP_DURING { St, DURING } UNFOLD DURING ) AS T2 :

Воспользуемся обычной операцией реляционного вычитания.

WITH ( Tl MINOS Т2 ) AS ТЗ : Отношение ТЗ выглядит так.

s#

DURING

S2

[d07,d07]

S3

[d03.d03]

S3

[d04,d04]

S3

[dOS.dOS]

S3

[d06,d06]

S3

[d07,d07]

S5

[d02,d02]

S5

[d03,d03]

S5

[d04,d04]

S5

[dOS,d05]

S5

[d06,d06]

S5

[d07,d07]

S5

[d08,d08]

S5

[d09,d09]

S5

\dlO,dlO]

И наконец, чтобы получить требуемый результат, свернем отношение ТЗ по атри­буту DURING.

s#

DURING

S2

[d07,d07]

S3

{d03,d07]

S5

[d02,dl0]

Теперь сформулируем запрос 4.2 в виде одного вложенного выражения.

( ( S_DURING { Si, DURING } UNFOLD DURING } MINUS

( SP DURING { Si, DURING } UNFOLD DURING ) ) COALESCE DURING

Как уже отмечалось, всю операцию, обозначаемую этим выражением, часто называ­ют хронологической разностью (точнее, "хронологической разностью" между проек­циями S_DURING и SP_DURING по атрибутам St и DURING).

Замечание. Как и хронологическая проекция, хронологическая разность не является, строго говоря, разностью как таковой, а представляет собой "хронологический аналог" обычной разности.

10 Обратите внимание, что для операции временной проекции явного сокращения мы не определяли.

Однако это еще не все. Выражения, подобные приведенному выше и использующие "хронологическую разность", настолько часто встречаются на практике, что, пожалуй, стоит определить еще одно дополнительное сокращение10. А именно, целесообразно представить в виде единой операции приведенную ниже последовательность действий: а) развернуть оба операнда; б) получить разность; в) свернуть полученный результат. Кроме того, подобное сокращение имеет дополнительное преимущество — появляется возможность повышения производительности. Если используются длинные интервалы с мелкой зернистостью, то результат развертывания отношения может быть очень большим по сравнению с ее операндом. Если система будет реально материализовать оба развертывания, вычислять разность и затем путем свертывания получать резуль­тат, то такой запрос может выполняться "вечно" или же приводить к переполнению доступного дискового пространства. Выражение хронологической разности в виде од­ной операции может помочь оптимизатору "понять", что именно требуется, и, воз­можно, избежать реального выполнения каких-либо развертываний. Ниже предлагает­ся такое дополнительное сокращение.

Rl I_MINUS R2 ON А

Здесь R1 и R2— реляционные выражения, обозначающие отношения rl и г2 одного и того же типа, а Л — атрибут некоторого интервального типа, общего для обоих отноше­ний (префикс I , конечно же, указывает на "интервал"). Из сказанного выше должно быть более или менее ясно, что определяемое выражение будет семантически равно­сильно следующему выражению.

( ( Rl UNFOLD А ) MINUS ( R2 UNFOLD А ) ) COALESCE А

Дальнейшее обсуждение операторов вида "I ", подобных оператору I_MINUS, будет продолжено в упр. 22.2.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]