
3.7. Реляционное исчисление
Как отмечалось ранее, принципиальное различие между реляционной алгеброй и реляционным исчислением состоит в том, что в первом случае процесс получения искомого результата описывается явным образом путем указания набора операций, которые надо выполнить для получения результата, а во втором — указываются свойства искомого отношения без конкретизации процедуры его получения.
Внешне подходы сильно различаются: один из них предписывающий (реляционная алгебра), а другой описательный (реляционное исчисление). На более низком уровне рассмотрения подходы эквивалентны, так как любые выражения реляционной алгебры могут быть преобразованы в семантически эквивалентные выражения реляционного исчисления и наоборот. Возможность такого преобразования доказывалась многими авторами, в частности, для этого можно использовать алгоритм редукции Кодда.
Для названного алгоритма преобразования покажем на содержательном уровне возможности формулировки одного и того же запроса с помощью реляционной алгебры и реляционного исчисления на простом примере.
Пусть запрос выглядит следующим образом: «Получить номера и города поставщиков, выпускающих деталь Р2».
Словесно алгебраическая версия этого запроса описывается так:
образовать естественное соединение отношений S и SP по атрибуту П#;
выбрать из результата этого соединения кортежи с деталью Р2 (в поле Д# должна быть строка Р2);
спроецировать результат предыдущей операции на атрибуты П# и Город_П.
Этот же запрос в терминах реляционного исчисления можно сформулировать примерно так: «Получить атрибуты П# и Город__П для таких поставщиков, для которых существует поставка в отношении SP с тем же значением атрибута П# и со значением Р" атрибута Д#».
Результатом выполнения запроса будет отношение R вида:
П# |
Город_П |
S1 |
Москва |
S2 |
Киев |
S3 |
Киев |
S4 |
Москва |
Преимуществом реляционного исчисления перед реляционной алгеброй можно считать то, что пользователю не требуется самому строить алгоритм выполнения запроса. Программа СУБД (при достаточной ее интеллектуальности) сама строит эффективный алгоритм.
Отметим, что поставленную задачу выборки можно решить более оптимально с точки зрения потребности в оперативной памяти. Более экономичный вариант решения в терминах операциях реляционной алгебры выглядит так:
выбрать из отношения SP кортежи, относящиеся к детали Р2;
выполнить естественное соединение отношения S и отношения, полученного на предыдущем шаге;
спроецировать текущее отношение на атрибуты П# и Город_П.
Экономия памяти при реализации этого алгоритма в сравнении с первоначальным вариантом достигается за счет снижения размерности участвующих в операциях временных таблиц, необходимых для хранения промежуточных результатов. Если в предыдущем случае размерность временной таблицы была 12*6 (12 строк на 6 колонок), то в последнем случае — 4*6.
Математической основой реляционного исчисления является исчисление предикатов — один из разделов математической логики. Понятие реляционного исчисления как языка работы с базами данных впервые предложено Коддом. Им же был разработан язык ALPHA — прототип программно реализованного языка QUEL, который некоторое время конкурировал с языком SQL.
Существует два варианта исчислений: исчисление кортежей и исчисление доменов. В первом случае для описания отношений используются переменные, допустимыми значениями которых являются кортежи отношения, а во втором случае — элементы домена.
Реляционное исчисление, основанное на кортежах (исчисление кортежей), предложено и реализовано при разработке упоминавшегося языка ALPHA. В нем, как и в процедурных языках программирования, сначала нужно описать используемые переменные, а затем записывать некоторые выражения.
Описательную часть исчисления можно представить в виде:
RANGE OF <переменная> IS <список>,
где прописными буквами записаны ключевые слова языка, <переменная>—идентификатор переменной кортежа (области значений), а <список> — последовательность одного или более элементов, разделенных запятыми, то есть конструкция вида: х1 [, х2 [..., xn]...].
Вся конструкция RANGE указывает идентификатор переменной и область ее допустимых значений. Список элементов xt х1 [, х2 [..., xn]...] содержит элементы, каждый из которых является либо отношением, либо выражением над отношением (порядок записи выражений описывается далее). Все элементы списка должны быть совместимы по типу, то есть соответствующие элементам отношения должны иметь идентичные заголовки. Область допустимых значений <переменной> образуется путем объединения значений всех элементов списка. Так, запись вида RANGE OF T IS X1,X2 означает, что область определения переменной Т включает в себя все значения из отношения, которое является объединением отношений XI и Х2.
Пример 1. Варианты описаний.
RANGE OF SX IS S;
RANGE OF SPX IS SP;
RANGE OF SY IS (SX) WHERE SX.Город_П = 'Москва',
(SX) WHERE EXISTS SPX (SPX.II# = SX.II# AND SРХ.Д# = 'P1');
Переменные SX и SPX в первых двух примерах определены соответственно на отношениях S и SP соответственно (рис. 3.7). Третий пример иллюстрирует запись выражений при определении переменной кортежа. Переменная SY здесь может принимать значения из множества кортежей отношения S для поставщиков из Лондона или поставщиков, которые поставляют деталь Р1 (или для тех и других).
Синтаксис выражений исчисления рассматривается ниже. Запись выражения, формулирующего запрос на языке исчисления кортежей с помощью формы Бэкуса-Наура, упрощенно можно представить следующим образом:
<выражение> ::= (у1 [, у2 [..., уm]...]) [ WHERE wff ]
уi ::= {<переменная> | <переменная>.<атрибут> } [ AS <атрибут> ]
wff ::= <условие> |
NOT wff |
<условие> AND wff |
<условие> OR wff |
IF <условие> THEN wff |
EXISTS <переменная> (wff) |
FORALL <переменная> (wff) |
(wff)
Общий смысл записи выражения состоит в перечислении атрибутов результирующего (целевого) отношения, атрибуты которого должны удовлетворять условию истинности формулы wff (well formulated formula — правильно построенная формула). Список атрибутов целевого отношения, или целевой список, в терминах реляционной алгебры по существу определяет операцию проекции, а формула wff — селекцию кортежей.
В паре <переменная>.<атрибут> первая составляющая служит для указания переменной кортежа (определенной конструкцией RANGE), а вторая — для определения атрибута отношения, на котором изменяется переменная кортежа. Необязательная часть «AS <атрибут>» используется для переименования целевого отношения. Если она отсутствует, то имя атрибута целевого отношения наследуется от соответствующего имени атрибута исходного отношения.
Употребление в качестве элемента целевого отношения просто имени переменной Т равносильно перечислению в списке всех соответствующих атрибутов, т. е. Т.А1, Т.А2, ... , Т.Аn, где А1, А2, ..., Аn — атрибуты отношения, сопоставляемого с переменной Т.
Пример 2. Варианты записи пары <переменная>.<атрибут>.
SX.П#
SX.П# AS Город_Поставщика
SX
SX.П#, SХ.Город_П AS Город_Поставщика, РХ.Д#, РХ.Город_Д# AS
Город_Детали
В приведенном определении wff <условие> представляет собой либо формулу wff, заключенную в скобки, либо простое сравнение вида:
<операнд1> <операнд2>,
где в качестве любого операнда выступает переменная или скалярная константа, а символ обозначает операцию сравнения =, ≠, >, ≥, <, ≤ и т. д.
Ключевые слова NOT, AND и OR обозначают логические операции соответственна И, НЕ и ИЛИ. Ключевые слова IF и THEN переводятся соответственно «если» и «то». И наконец, ключевые слова EXISTS и FORALL называются кванторами. Первый из них — квантор существования, а второй — квантор всеобщности. Рассмотрим эти кванторы несколько подробнее.
Формула wff вида: EXISTS x (f) означает: «Существует по крайней мере одно такое значение переменной х, что вычисление формулы f дает значение истина». Выражение вида: FORALL x (f) интерпретируется как высказывание: «Для всех значений переменной х вычисление формулы f дает значение истина». В общем случае переменные кортежей в формулах могут быть свободными или связанными. В формулах EXISTS x (1) и FORALL х (f) переменные кортежей х всегда являются связанными.
Пример 3. Запись выражения.
Приведем запись выражения, соответствующее запросу: «Получить имена поставщиков, которые поставляют все детали».
SХ.Город_П WHERE FORALL PX (EXISTS SPX
(SPX.П# = SX.П# AND SPX.Д# = SX.Д# ))
Равносильное этому выражение выглядит так:
SX.Город_П WHERE NOT EXISTS PX (NOT EXISTS SPX
(SPX.П# = SX.П# AND SPX.Д# = SХ.Д# ))
Описанное исчисление не обладает вычислительной полнотой, так как не позволяет выполнять вычисления, связанные с обработкой данных в базах. Добавление вычислительных функций в это исчисление можно реализовать путем расширения определения операндов сравнения и элементов целевого списка таким образом, чтобы они допускали использование скалярных выражений с литералами, ссылками на атрибуты и итоговыми функциями. В качестве итоговых могут выступать следующие функции: COUNT (количество), SUM (сумма), AVG (среднее), МАХ (максимальное), MIN (минимальное). Для целевых элементов целесообразно использовать спецификацию вида «AS <имя атрибута>», позволяющую явно задать имя результирующему атрибуту, если нет очевидного наследуемого имени.
Пример 4. Запись запроса.
Пусть требуется получить информацию о каждой поставке с полными данными о деталях и общем весе поставки. Запрос на дополненном функциями языке реляционного исчисления кортежей может выглядеть следующим образом:
(SPX.П#, SPX-Количество, РХ, РХ.Вес * SРХ.Количество AS Общий_Вес) WHERE РХ.Д# = SРХ.Д#
Вариант реляционного исчисления, основанного на доменах (исчисление доменов), предложен Лакроиксом и Пиротте (Lacroix and Pirotte), которые также разработали на его основе соответствующий язык ILL. Другими языками, основанными на исчислении доменов, являются: FQL, DEDUCE, а также QBE с некоторыми оговорками.
По утверждению Дейта, язык QBE включает элементы исчисления кортежей и исчисления доменов, но более близок ко второму. Он не является реляционно полным, так как не поддерживает операцию отрицания квантора существования (NOT EXISTS). Несмотря на этот недостаток, язык QBE получил широкое распространение в современных СУБД. Тем более, что реализации этого языка, как правило, шире исходного языка.
Исчисление доменов имеет много сходства с исчислением кортежей. В отличие от исчисления кортежей, в исчислении доменов основой любого выражения запроса выступают переменные доменов. Переменная домена — это скалярная переменная, значения которой охватывают элементы некоторого домена.
Большая часть различий рассматриваемых исчислений заключается в том, что исчисление доменов поддерживает дополнительную форму условия, называемую условием принадлежности. В общем виде условие принадлежности записывается в виде:
R(A1:υ1,A2: υ2,...),
где Ai — атрибут отношения R, а υi — переменная домена или литерал. Проверяемое условие истинно, если и только если существует кортеж в отношении R, имеющий атрибуты А, равные заданным в выражении соответствующим значениям υ.
Например, выражение SP (П# : ‘Sl’, Д# : ‘РГ’) истинно, если в отношении SP существует хотя бы один кортеж со значением 'S1' атрибута П# и значением ‘РГ’ атрибута Д#. Аналогично, выражение SP (П#: SX, Д#: РХ) истинно, если в отношении SP существует кортеж, в котором значение атрибута П# эквивалентно текущему значению переменной домена SX, а значение атрибута Д# эквивалентно текущему значению переменной домена РХ.
В следующих примерах будем подразумевать существование (объявленное каким-либо образом, подобно оператору RANGE исчисления кортежей) следующих переменных доменов: SX (домен П#), РХ (домен Д#), NAMEX (домен Имя).
Пример 5. Выражения исчисления доменов.
(SX) WHERE S (П# : SX) (SX) WHERE S (П# : SX, Город_П : 'Москва') NAMEX WHERE EXISTS SX ( S (П# : SX, Имя: NAMEX) AND FORALL PX ( IF P (Д# : РХ ) THEN SP (П# : SX, Д# : PX ) ) )
Первое выражение означает множество всех номеров поставщиков отношения S, второе — множество номеров поставщиков из Лондона. Третье выражение соответствует запросу на получение имен поставщиков, производящих все детали.