Операция расширения

Читатель, возможно, заметил, что в описанной нами алгебре нет средств для скалярных вычислений. Конечно, на практике такие возможности необходимы. Например, может понадобиться запросить из базы данных арифметическое выражение, такое как WEIGHT*454, или сослаться на такое значение в выражении WHERE при выборке (вспомним, что вес в нашем примере приведен в фунтах; выражение WEIGHT*454 переводит этот вес в граммы). Для обеспечения таких возможностей и предназначена операция расширения. Точнее, с помощью этой операции из определенного отношения (по крайней мере концептуально) создается новое отношение; оно похоже на на­чальное, но содержит дополнительный атрибут, значения которого получены посред­ством некоторых скалярных вычислений. Например, можно написать:

EXTEND Р ADD (WEIGНТ * 454) AS GMWT

С помощью этого выражения создается новое отношение с таким же заголовком, как у отношения Р, за исключением дополнительного атрибута GMWT. Каждый кортеж этого отношения совпадает с соответствующим кортежем отношения Р, но содержит еще дополнительное значение GMWT, вычисляемое в соответствии с указанным вы­ражением (рис. 6.1 О).

Рис. 6. 10. Пример операции расширения

Теперь можно использовать атрибут GMWT в операциях проекции, выборки и т.д. Например, так:

(EXTEND Р ADD (WEIGНТ * 454) AS GMWT) WHERE GMWT > 10000

Замечание. Конечно, более дружественный пользовательский язык позволяет вставлять выражения непосредственно с помощью оператора WНERE:

P WНERE (WEIGНТ * 454) > 10000

Однако такая возможность - это просто синтаксическое усовершенствование.

Можно включить в синтаксис, приведенный на рис. 6.2, операцию EXTEND, добавив новый вид унарных выражений со следующим синтаксисом:

EXTEND tеrm ADD scalar-ехрression AS attribute

Например:

EXTEND S ADD exp AS Z

Результатом этого выражения (обратите внимание, что это выражение, а не команда или оператор) будет отношение с заголовком, эквивалентным заголовку отношения А, расширенному новым атрибутом Z[5],который подсчитывается вычисление скалярного выражения ехр для кортежа отношения А. При этом отношение А не должно иметь атрибута Z и выражение ехр не должно ссылаться на атрибут Z. Заметьте, что кардинальное число результата равно кардинальному числу отношения А, а, степень результата равна степени отношения А плюс единица.

Приведем еще несколько примеров.

1.. EXTEND S ADD ‘Supplier” AS TAG

Это выражение эффективно дополняет каждый кортеж отношения S символьным значением "Supplier" (конечно, скалярный литерал (символьное значение) является простым случаем скалярного выражения).

2. EXTEND (Р JOIN SP) ADD (WEIGНТ * QTY) AS SHIPWT

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

3. (EXTEND S ADD CITY AS SCITY) [ S#, SNAME, STATUS, SCITY ]

Имя атрибута, такое как CITY, - также допустимое скалярное выражение. Заметьте, что этот пример равносилен следующему:

S RENAME CITY AS SCITY

Иными словами, оператор RENAME не примитивен! Он может быть определен через оператор EXTEND.

4. EXTEND S ADD COUNT ((SP RENAME S# AS X) WHERE X = S#) AS NP

Результат этого выражения показан на рис. 6.11.

             
  S# SNAME STATUS CITY NP  
  S1 S2 S3 S4 S5 Smith Jones Black Clark Adams   London Paris Paris London Athens    
             

Рис. 6. 11. Еще один пример операции расширения

Пояснения:

q Для данного поставщика в отношении S выражение

((SP RENAME S# AS X) WHERE X = S#)

дает множество поставок, соответствующих этому поставщику.

q Затем «итоговая функция» COUNT применяется для этого множества поставок и возвращает соответствующее кардинальное число (которое является, конечно, скалярным значением).

Атрибут NP в результирующем отношении представляет количество деталей, поставляемых поставщиком, который идентифицируется соответствующим значением S#. Обратите внимание, в частности, на значение NP для S5; множество кортежей отношения SP для этого поставщика пусто, поэтому функция COUNT возвращает нуль.

Замечание. Как указывалось ранее, функция COUNT – это пример итоговой функции (т. е. функции, берущей в качестве аргумента множество значений и возвращающей одно значение). Функция SUM (сумма), AVG (среднее значение), MAX (максимальное значение) и MIN (минимальное значение) – это хорошо известные примеры итоговых функций. Если аргумент такой функции будет пустым множеством, то функция COUNT (как объяснено выше) возвращает нуль; функция SUM также возвращает нуль; функция MAX и MIN возвращают максимальное и минимальное значения соответствующего домена, а функция AVG генерирует исключительную ситуацию.

Вернемся к оператору EXTEND: подвыражения, подобные

((SP RENAME S# AS X) WHERE X = S#)

(т. е. выражения, использующие переименование атрибутов с последующей проверкой равенства переименованного атрибута и атрибута «расширяемого» отношения, имя которого такое же, как первоначальное имя переименованного атрибута), очень часто используются на практике, и поэтому имеет смысл ввести подходящее сокращение. Условимся считать, что

MATCHING expression)

(где expression может быть произвольным реляционным выражением) – это выражение, допустимое в качестве аргумента для итоговой функции, используемой в операторе EXTEND, со следующей интерпретацией. Пусть оператор EXTEND имеет вид

EXTEND R1 ADD agg-fun (MATCHING R2) AS…

Пусть У – набор общих атрибутов отношений R1 и R2. Тогда выражение (MATCHING R2) по определению является сокращением выражения.

((R2 RENAME Y AS X) WHERE X = Y)

для некоторого соответствующего (в общем случае произвольного) имени Х. С учетом этого упрощения общее выражение первоначального запроса выглядит следующим образом:

EXTEND S ADD COUNT (MATCHING SP) AS NP

5. И наконец, можно также ввести сокращение для множественной операции EXTEND, как показано в следующем примере (выше в этой главе обсуждалось множественное переименование):

(EXTEND P ADD CITY AS PCITY, (WEIGHT * 454) AS GMWT)

Операция подведения итогов

Как мы уже убедились, операция расширения обеспечивает возможность «горизонтального», или «построчного», вычисления в алгебре. Операция SUMMARIZE (подведение итогов) выполняет аналогичную функцию для «вертикальных» вычислений. Например, с помощью выражения

SUMMARIZE SP BY (P#) ADD SUM (QTY) AS TOTQTY

вычисляется отношение с заголовком {P#, TOTQTY}, в котором существует один кортеж для каждого значения P# в отношении SP; в этом кортеже содержится значение P# и соответствующее общее количество деталей (рис. 6.12). Другими словами, отношение Р концептуально «перегруппировано» в множества кортежей (по одному множеству для каждого значения Р#), и из каждой группы в общий результат сгенерирован один кортеж[6].

       
  P# TOTQTY  
  P1 P2 P3 P4 P5 P6    
       

Рис. 6. 12. Пример выполнения операции SUMMARIZE

В терминах синтаксиса рис. 6. 2. введем новый вид унарных выражений:

SUMMARIZE term BY (attribute-commalist)

ADD aggregate-expression AS attribute

Например:

SUMMARIZE A BY (A1, A2, …,An) ADD exp AS Z

Здесь A1, A2, …,An – отдельные атрибуты отношения А. Результатом этого выражения (обратите внимание, что приведенный пример является выражением, а не командой или оператором) будет отношение с заголовком {A1, A2, …,An, Z}[7] и с телом, содержащим все такие кортежи t, которые являются кортежами проекции отношения А по атрибутам A1, A2, …,An, расширенного значением для нового атрибута Z. Заметьте, что кардинальное число результата равно кардинальному числу проекции отношения А по атрибутам A1, A2, …,An, а степень результата равна степени такой проекции плюс единица.

Вот другой пример, который показывает, что операнд term оператора SUMMARIZE может быть произвольным реляционным выражением, заключенным в круглые скобки:

SUMMARIZE (P JOIN SP) BY (CITY) ADD COUNT AS NSP

результат будет подобен следующему:

CITY NSP
London Paris Rome  

Другими словами, результат содержит один кортеж для каждого из трех городов (Лондона, Парижа и Рима), и в каждом кортеже показано количество поставок деталей из этих городов.

Необходимо отметить, что операция SUMMARIZE не такая простая, как EXTEND. Приведем примеры, иллюстрирующие возможности ловушки.

1. SUMMARIZE S R BY () ADD SUM (QTY) AS GRANDTOTAL

В этом примере атрибутов, по которым подводится итог, нет вообще. Предположим на некоторое время, что отношение SP содержит по крайней мере один кортеж и все кортежи отношения имеют “одинаковое значение” по пустому множеству атрибутов, т. е. итоговое вычисление производится только один раз для всего отношения. Таким образом, вычисление всего выражения сводится к одному отношению с одним атрибутом и одним кортежем; атрибут называется GRANDTOTAL, а единственное скалярное значение в единственном результирующем кортеже является общим для всех значений атрибута QTY в исходном отношении SP.

Если, с другой стороны, исходное отношение SP не имеет кортежей совсем, то нет групп, а следовательно, нет и результирующих кортежей, т. е. результирующее отношение также будет пустым. Таким образом, операция SUMMARIZE имеет следующий (незначительный) недостаток: ее нельзя использовать для получения итога (например, с помощью функции COUNT) пустого множества.

2. SUMMARIZE S R BY (S#) ADD COUNT AS NP

Результат этого примера будет таким:

S# NP
S1 S2 S3 S4  

Как видите, результат не включает кортеж для поставщика S5 (с количеством поставляемых деталей, равным нулю) несмотря на то, что поставщик действительно поставляет ноль деталей. Причина, конечно, заключается в том, что поставщика S5 нет в отношении SP. Поэтому общий результат не совсем очевиден или, по крайней мере, его очевидность можно оспорить (Конечно, вы уже видели способ получения аналогичного результата, включающего поставщика S5. Если вы его подзабыли, вернитесь и просмотрите примеры оператора EXТEND.)

Заметьте, что для функции COUNТ, в отличие от других итоговых функций, не требуется никаких аргументов. Строго говоря, функция COUNТ не является необходимой, поскольку она эквивалентна SUМ(1).

Рассмотрим запрос "Получить города, в которых хранится более пяти красных деталей":

((SUMMARIZE (Р WНERE COLOR = 'Red')

ВУ (CIТY) ADD COUNТ AS N) WНERE N > 5) [ CIТY ]

Теперь предположим, что мы изменили запрос следующим образом: "Получить города, в которых хранится пять красных деталей или меньше". Простая замена ">" на "≤" в предыдущем выражении

((SUMMARIZE (Р WНERE COLOR = 'Red')

ВУ (CIТY) ADD COUNТ AS N) WНERE N ≤ 5) [ CIТY ]

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

P [ CIТY ] МINUS xyz

Здесь xyz - выражение, приведенное выше для первого запроса.

Замечание. Проблема, показанная в этом примере, в действительности не является проблемой самой операции SUММARIZE: она вызвана тем фактом, что аргумент этой операции (выборка красных деталей отношения Р) уже исключает детали, которые имеют не красный цвет. Однако этот факт не делает результат более очевидным.

4. И наконец, мы можем ввести сокращение для множественной операции подведения итогов, как показано в следующем примере (выше в этой главе приводились обсуждения множественного переименования и множественного расширения):

(SUMMARIZЕ SP ВУ (P#) ADD SUM (QTY) AS ТOTQTY,

AVG (QTY) AS AVGQTY)

В заключение отметим еще два немаловажных момента.

5. В операции SUММARIZE (как и в операции DIVIDEBY) возникают затруднения при использовании пустых отношений. К сожалению, пересмотренная форма этого оператора, в которой устранены проблемы с пустыми отношениями, значительно сложнее первоначального оператора. Эта форма описана в комментариях к [6.3].

6. Возможно, читатель понимает, что оператор SUММARIZE не примитивен - его можно сымитировать с помощью оператора EXТEND (при этом будут использоваться определения итоговых функций; дальнейшее обсуждение по этому вопросу приводится в главе 7). Однако оператор SUММARIZE часто требуется на практике и его введение вполне оправдано.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: