Рекурсивные запросы

Автор: Пользователь скрыл имя, 29 Ноября 2011 в 22:21, контрольная работа

Описание работы

Традиционно язык SQL никогда не обладал возможностью формулировки рекурсивных запросов, где под рекурсивным запросом мы понимаем запрос к таблице, которая сама каким-либо образом изменяется при выполнении этого запроса. Это заложено в базовую семантику оператора SQL: до выполнения раздела WHERE результат раздела FROM должен быть полностью вычислен.
Однако разработчикам приложений часто приходится решать задачи, для которых недостаточно традиционных средств формулировки запросов языка SQL: например, нахождение маршрута движения между двумя заданными географическими точками, определения общего набора комплектующих для сбора некоторого агрегата и т.д. Компании-производители SQL-ориентированных СУБД пытались удовлетворять такие потребности за счет частных решений, обладающих ограниченными рекурсивными свойствами, но до появления стандарта SQL:1999 общие стандартизованные средства отсутствовали.

Содержание

Введение………………….……………………………………...……………….3
1 Рекурсивные запросы .…………………….………………………….……….4
1.1 Определения, относящиеся к рекурсии…………………………………….4
1.2 Рекурсивные запросы с разделом WITH……………………………………7
1.3 Рекурсивные представления………………………………………………..12
Заключение…………………………………………………………………………...14
Список литературы…………………………………………………………....……..15

Работа содержит 1 файл

КР Современные СУБД.doc

— 196.50 Кб (Скачать)

     (SELECT CONTAINING_PART, CONTAINED_PART, 1, 0.00

     FROM CAR

     WHERE CONTAINING_PART = ''

  UNION ALL

     SELECT CAR.CONTAINING_PART, CAR.CONTAINED_PART,

            CAR.NUMBER_OF_PARTS, CAR.NUMBER_OF_PARTS *

            CAR.PART_COST

     FROM CAR, PARTS

     WHERE PARTS.PART_NUMBER = CAR.CONTAINING_PART)

     SEARCH BREADTH FIRST

     BY CONTAINING_PART, CONTAINED_PART

     SET ORDER_COLUMN

SELECT PART_NUMBER, NUMBER_OF PARTS, COST

FROM PARTS

ORDER BY ORDER_COLUMN;

      В списке столбцов сортировки раздела  SEARCH должны указываться имена столбцов виртуальной таблицы, определенной в разделе WITH. Поскольку в данном случае мы хотим, чтобы в результате сначала появлялись все конструктивные элементы одного уровня (CONTAINING_PART), а затем все их подэлементы (CONTAINED_PART), в список выборки рекурсивного запроса PARTS добавлен столбец CONTAINING_PART, который не используется нигде, кроме раздела SEARCH. В разделе SET к результирующей таблице рекурсивного запроса добавлен столбец, который мы назвали ORDER_COLUMN. Название соответствует природе столбца, потому что при выполнении рекурсивного запроса в этот столбец автоматически заносятся значения, характеризующие порядок генерируемых строк в соответствии с выбранным способом обхода иерархии. Чтобы строки результата основного запроса появлялись в должном порядке, в этом запросе требуется наличие раздела ORDER BY с указанием столбца, определенного в разделе SET.

      Раздел CYRCLE

      Наконец, обсудим, для чего нужен раздел CYRCLE. Дело в том, что иногда сами данные, хранимые в таблицах базы данных, могут иметь циклическую природу. Представим себе, например, компанию, в которой существует совет директоров, являющийся высшим органом управления компанией. Обычным случаем является тот, когда по крайней мере один из членов совета директоров является простым служащим этой же компании (например, он может входить в совет директоров как представитель профсоюза). Назовем данного члена совета директоров EMP_DIR. Как член совета директоров, EMP_DIR «управляет» деятельностью президента компании. С другой стороны, как служащий компании, EMP_DIR находится в прямом или косвенном подчинении у президента компании. Такое положение может привести к зацикливанию выполнения рекурсивных запросов. Раздел CYRCLE обеспечивает некоторую возможность распознавать подобные ситуации. Если у пользователя имеется полная уверенность в отсутствии циклов в данных, к которым адресуется рекурсивный запрос, то использование раздела CYRCLE не требуется.

      

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

      Обсудим все это более формально. Для удобства воспроизведем еще раз синтаксис раздела CYRCLE.

cycle_clause ::= CYCLE cycle_column_name_comma_list

    SET cycle_mark_column_name TO value_expression_1

    DEFAULT value_expression_2

    USING path_column_name

      В списке cycle_column_name_comma_list указываются имена одного или нескольких столбцов, которые используются для идентификации новых строк результата на основе строк, уже входящих в результат. Раздел SET приводит к образованию нового столбца результирующей таблицы. Для строк, которые попадают в результат первый раз, в столбец cycle_mark_column_name заносится значение выражения value_expression_2. В повторно заносимых строках значение столбца – value_expression_1. Типом данных этого столбца является тип символьных строк длины один, так что в качестве value_expression_1 и value_expression_2 разумно использовать константы '0' и '1' или 'Y' и 'N'.

      Раздел  USING приводит к образованию еще одного дополнительного столбца результата с именем path_column_name. Типом данных столбца является ARRAY, причем кардинальность этого типа предполагается достаточно большой, чтобы сохранить информацию обо всех строках, попавших в результат. Элементы массива имеют «строчный тип» (row type), содержащий столько столбцов, сколько их указано в списке раздела CYRCLE. Каждый элемент массива соответствует строке результата, и в его столбцах содержится копия значений соответствующих столбцов этой строки. Вот пример запроса, содержащего раздел CYRCLE:

WITH RECURSIVE PARTS (PART_NUMBER,

      NUMBER_OF_PARTS, COST) AS

   (SELECT CONTAINED_PART, 1, 0.00

      FROM CAR

      WHERE CONTAINING_PART = ''

   UNION ALL

      SELECT CAR.CONTAINED_PART, CAR.NUMBER_OF_PARTS,

         CAR.NUMBER_OF_PARTS * CAR.PART_COST

      FROM CAR, PARTS

      WHERE PARTS.PART_NUMBER = CAR.CONTAINING_PART)

      CYRCLE CONTAINED_PART

      SET CYCLEMARK TO 'Y' DEFAULT 'N'

      USING CYRCLEPATH

SELECT PART_NUMBER, SUM(NUMBER_OF PARTS), SUM(COST)

FROM PARTS

ORDER BY PART_NUMBER;

      Имена столбцов CYCLEMARK и CYRCLEPATH выбраны произвольным образом – требуется только, чтобы имена этих столбцов отличались от имен столбцов рекурсивного запроса. При выполнении запроса строки, удовлетворяющие его условию, накапливаются в результирующей таблице. Но, кроме того, эти строки «кэшируются» в столбце CYRCLEPATH. При попытке добавления к результату новой строки на основе текущего содержимого столбца CYRCLEPATH проверяется, не содержится ли она уже в результате. Если не содержится, то данные об этой строке добавляются к столбцу CYRCLEPATH (к массиву добавляется новый элемент), в столбец CYCLEMARK этой строки заносится значение 'N', и строка добавляется к результату. Иначе в столбец CYCLEMARK соответствующей строки результата заносится значение 'Y', означающее, что от этой строки начинается цикл.

      1.3 Рекурсивные представления

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

CREATE RECURSIVE VIEW table_name

   [ column_name_comma_list ]

   AS query_expression

      Хотя  для того, чтобы представление  было рекурсивным, требуется рекурсивность  определяющего выражения запроса (т.е. в нем должна присутствовать спецификация RECURSIVE); наличие избыточного ключевого RECURSIVE в определении рекурсивного представления является обязательным. Как говорят авторы стандарта, это сделано для того, чтобы избежать случайного появления непредусмотренных рекурсивных представлений. Наконец, обратите внимание на то, что еще не обсуждавшийся нами необязательный раздел WITH CHECK OPTION не может присутствовать в определении рекурсивного представления (по той причине, что разработчики стандарта не смогли найти разумной интерпретации для комбинации RECURSIVE и WITH CHECK OPTION).

      В заключение этого раздела могу сказать, что лично мне механизм рекурсии, предлагаемый в стандарте SQL, представляется громоздким и ограниченным. Кроме  того, насколько мне известно, компании, поставляющие SQL-ориентированные СУБД, не спешат внедрять в свои продукты средства рекурсии в соответствии со стандартом SQL:1999 (или, по крайней мере, не слишком их афишируют).  

      

      

     Заключение

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

      Однако  далеко не каждое предприятие может  позволить себе одновременно поддерживать оперативную базу данных для работы обычных приложений оперативной обработки транзакций (OLTP), таких, как бухгалтерские, кадровые и другие приложения, и аналитическую базу данных для приложений оперативной аналитической обработки (OLAP). Приходится выполнять аналитические приложения над детальными оперативными базами данных, и эти приложения обращаются к СУБД с многочисленными трудоемкими запросами с разделами GROUP BY и вызовами агрегатных функций.

      Разработчики  стандарта языка SQL старались одновременно решить две задачи: сократить число запросов, требуемых в аналитических приложениях, и добиться снижения стоимости запросов с разделом GROUP BY, обеспечивающих требуемые суммарные данные. В этой лекции мы обсудим наиболее важные, с нашей точки зрения, конструкции языка SQL, облегчающие формулировку, выполнение и использование результатов аналитических запросов: разделы GROUP BY ROLLUP и GROUP BY CUBE и новую агрегатную функцию GROUPING, позволяющую правильно трактовать результаты аналитических запросов при наличии неопределенных значений.

      Список  литературы

      1. С. Кузнецов. Базы данных. Вводный  курс. 2008 г.

      2. Сайт в Интеренете www.intuit.ru. 

  

    

Информация о работе Рекурсивные запросы