
4.7. Реляционное исчисление
Принципиальное различие между реляционной алгеброй и реляционным исчислением состоит в том, что в реляционной алгебре процесс получения искомого результата описывается явным образом путем указания набора операций, которые надо выполнить для получения результата. А в реляционном исчислении – указываются свойства искомого отношения без конкретизации процедуры его получения.
Внешне подходы сильно различаются: один из них предписывающий (реляционная алгебра), а другой описательный (реляционное исчисление). На более низком уровне эти подходы эквивалентны, т.к. любое выражение реляционной алгебры может быть преобразовано в семантически эквивалентное выражение реляционного исчисления и наоборот. Для этого можно использовать алгоритм редукции Кодда.
Рассмотрим пример формулирования одного и того же запроса с помощью реляционной алгебры и реляционного исчисления.
Запрос: «Получить номера и города поставщиков, выпускающих деталь Р2».
В терминах реляционной алгебры словесно этот запрос описывается так:
Образовать естественное соединение отношений S и SP по атрибуту П# ;
Выбрать из результата этого соединения кортежи с деталью Р2 (в поле Д# должна быть строка Р2);
Спроецировать результат предыдущей операции на атрибуты П# и Город_П.
В терминах реляционного исчисления этот запрос словесно формулируется так:
«Получить атрибуты П# и Город_П для таких поставщиков, для которых существует поставка в отношении SP с тем же значением атрибута П# и со значением Р2 атрибута Д#».
Результатом выполнения запроса будет отношение R вида:
-
П#
Город_П
S1
Москва
S2
Иркутск
S3
Иркутск
S4
Москва
Преимуществом реляционного исчисления перед реляционной алгеброй является то, что пользователю не требуется самому строить алгоритм выполнения запроса. Программа СУБД сама строит эффективный алгоритм.
Поставленную задачу выборки можно решить более оптимально с точки зрения потребности в оперативной памяти. Более экономичный вариант решения в терминах реляционной алгебры выглядит так:
Выбрать из отношения SP кортежи, относящиеся к детали Р2;
Выполнить естественное соединение отношения S и отношения, полученного на предыдущем шаге;
Спроецировать текущее отношение на атрибуты П# и Город_П.
В этом случае снижается размерность участвующих в операциях временных таблиц, необходимых для хранения промежуточных результатов (первый вариант – таблица была 12*6 (12 строк на 6 столбцов), второй вариант – 4*6).
Математической основой реляционного исчисления является исчисление предикатов (из математической логики). Понятие реляционного исчисления, как языка работы с базами данных, впервые предложено Коддом. Он разработал язык ALPHA – прототип программно реализованного языка QUEL, который некоторое время конкурировал с языком SQL.
Существует два варианта исчислений: исчисление кортежей и исчисление доменов. В первом случае для описания отношений используются переменные, допустимыми значениями которых являются кортежи отношения, а во втором случае – элементы домена.
Реляционное исчисление, основанное на кортежах (исчисление кортежей) предложено и реализовано при разработке языка ALPHA. В нем, как и в процедурных языках программирования, сначала нужно описать используемые переменные, а затем записывать некоторые выражения.
Описательную часть исчисления можно представить в виде:
RANGE OF <переменная> IS <список>,
где прописными буквами
записаны ключевые слова языка, <переменная>
- идентификатор переменной кортежа
(области значений), а <список> -
последовательность одного или более
элементов, разделенных запятыми, т.е.
инструкции вида:
.
Вся конструкция RANGE указывает идентификатор переменной и область ее допустимых значений. Список элементов содержит элементы, каждый из которых является либо отношением, либо выражением над отношением. Все элементы списка должны быть совместимы по типу, т.е. соответствующие элементам отношения должны иметь идентичные заголовки. Область допустимых значений <переменной> образуется путем объединения значений всех элементов списка. Так, запись вида RANGE OF T IS X1, X2 означает, что область определения переменной Т включает в себя все значения из отношения, которое является объединением отношений X1 и X2.
Пример 1. Варианты описаний.
RANGE OF SX IS S;
RANGE OF SPX IS SP;
RANGE OF SY IS (SX) WHERE SX.Город_П = ‘Москва’,
(SX) WHERE EXISTS SPX (SPX. П# = SX.П# AND SPX.Д# = ‘Р1’).
Переменные SX и SPX в первых двух примерах определены соответственно на отношениях S и SP (рис. 4.6). Третий пример иллюстрирует запись выражений при определении переменной кортежа. Переменная SY здесь может принимать значения из множества кортежей отношения S для поставщиков из Москвы или поставщиков, которые поставляют детали Р1 (или для тех и других).
Запись выражения, формулирующего запрос на языке исчисления кортежей с помощью формы Бэкуса-Наура, можно представить следующим образом:
<выражение> ::= (y1 [,y2 […,ym]…]) [WHERE wff]
y ::= {<переменная>|<переменная>.<атрибут>} [AS <атрибут>]
wff::= <условие>|
NOT wff|
<условие> AND wff|
<условие> OR wff|
IF <условие> THEN wff|
EXISTS <переменная> (wff)|
FORALL <переменная> (wff)|
(wff)
Общий смысл записи выражения состоит в перечислении атрибутов результирующего (целевого) отношения, атрибуты которого должны удовлетворять условию истинности формулы wff (well formulated formula – правильно построенная формула). Список атрибутов целевого отношения, или целевой список, в терминах реляционной алгебры по существу определяет операцию проекции, а формула wff - селекцию кортежей. В паре <переменная>.<атрибут> первая составляющая служит для указания переменной кортежа (определенной конструкцией RANGE), а вторая – для определения атрибута отношения, на котором изменяется переменная кортежа. Необязательная часть «AS <атрибут>» используется для переименования целевого отношения. Если она отсутствует, то имя атрибута целевого отношения наследуется от соответствующего имени атрибута исходного отношения.
Употребление
в качестве элемента целевого отношения
просто имени переменной Т
равносильно перечислению в списке всех
соответствующих атрибутов, т.е.
где
- атрибуты отношения, сопоставляемого
с переменной Т.
Пример 2. Варианты записи пары <переменная>.<атрибут>.
SX.П#
SX.Город_П AS Город_Поставщика
SX
SX.П#, SX.Город_П AS Город_Поставщика, PX.Д#, PX.Город_Д # AS
Город_Детали
В приведенном определении правильно построенной формулы wff <условие> представляет собой либо формулу wff, заключенную в скобки, либо простое сравнение вида:
<операнд1><операнд2>,
где в качестве любого
операнда выступает переменная или
скалярная константа, а символ
обозначает операцию сравнения
и т.д.
Ключевые слова NOT, AND и OR обозначают логические операции соответственно: НЕ, И и ИЛИ. Ключевые слова IF и THEN переводятся соответственно «если» и «то». И, наконец, ключевые слова EXISTS и FORALL называются кванторами. Первый из них – квантор существования, а второй – квантор всеобщности.
Формула wff вида: EXISTS x(f) означает: «Существует по крайней мере одно такое значение переменной х, что вычисление формулы f дает значение истина». Выражение вида: FORALL x(f) интерпретируется как высказывание: «Для всех значений переменной х вычисление формулы f дает значение истина». В общем случае переменные кортежей в формулах могут быть свободными или связанными. В формулах EXISTS x(f) и FORALL x(f) переменные кортежей х всегда являются связанными.
Пример 3. Запись выражения.
Рассмотрим запись выражения, соответствующую запросу: «Получить города поставщиков, которые поставляют все детали».
Запрос можно сформулировать следующим образом: «Получить города поставщиков, относительно которых для всех деталей, представленных в отношении Р, существует по крайней мере один кортеж в отношении SP такой, что значения кода поставщика в отношениях S и SP совпадают и значения кода детали в отношениях P и SP совпадают».
SX.Город_П WHERE FORALL PX (EXISTS SPX (SPX.П# = SX.П# AND
SPX.Д# = РX.Д#))
Равносильное этому выражение выглядит так: «Получить города поставщиков согласно условию: не существует такой детали в отношении Р, для которой не существует в отношении SP, в котором код поставщика совпадает с кодом поставщика в отношении S и код детали совпадает с кодом детали в отношении P».
SX.Город_П WHERE NOT EXISTS PX (NOT EXISTS SPX
(SPX.П# = SX.П# AND SPX.Д# = РX.Д#))
Описанное исчисление не обладает вычислительной полнотой, т.к. не позволяет выполнять вычисления, связанные с обработкой данных в базах. Добавление вычислительных функций в это исчисление можно реализовать путем расширения определения операндов сравнения и элементов целевого списка таким образом, чтобы они допускали использование скалярных выражений с литералами, ссылками на атрибуты и итоговыми функциями. В качестве итоговых могут выступать следующие функции: COUNT (количество), SUM (сумма), AVG (среднее), MAX (максимальное), MIN (минимальное). Для целевых элементов целесообразно использовать спецификацию вида «AS <имя атрибута>», позволяющую явно задать имя результирующему атрибуту, если нет очевидного наследуемого имени.
Пример 4. Запись запроса.
Пусть требуется получить информацию о каждой поставке с полными данными о деталях и общем весе поставки. Запрос на дополненном функциями языке реляционного исчисления кортежей может выглядеть следующим образом:
(SPX.П#, SPX.Количество, PX, PX.Вес*SPX.Количество AS Общий_Вес) WHERE PX.Д# = SPX.Д#.
Вариант реляционного исчисления, основанного на доменах (исчисление доменов), предложен Лакроиксом и Пиротте, которые также разработали на его основе соответствующий язык ILL. Другими языками, основанными на исчислении доменов, являются: FQL, DEDUCE, а также QBE с некоторыми оговорками.
По утверждению Дейта, язык QBE включает элементы исчисления кортежей и исчисления доменов, но он не является реляционно полным, т.к. не поддерживает операцию отрицания квантора существования (NOT EXISTS). Несмотря на этот недостаток, язык QBE получил широкое распространение в современных СУБД. Тем более, что современные реализации этого языка, как правило, шире исходного языка.
Исчисление доменов имеет много сходства с исчислением кортежей. В отличие от исчисления кортежей, в исчислении доменов основой любого выражения запроса выступают переменные доменов. Переменная домена – это скалярная переменная, значения которой охватывают элементы некоторого домена.
Большая часть различий рассматриваемых исчислений заключается в том, что исчисление доменов поддерживает дополнительную форму условия называемую условием принадлежности. В общем случае условие принадлежности записывается в виде:
,
где Аi – атрибут отношения R, а i – переменная домена или литерал. Проверяемое условие истинно, тогда и только тогда, когда существует кортеж в отношении R, имеющий атрибуты A, равные заданным в выражении соответствующим значениям .
Например, выражение SP(П#: ‘S1’, Д#: ‘P1’) истинно тогда и только тогда, когда в отношении SP существует хотя бы один кортеж со значением ‘S1’ атрибута П# и значением ‘P1’ атрибута Д#. Аналогично, выражение SP(П#: SX, Д#: PX) истинно, если в отношении SP существует кортеж, в котором значение атрибута П# эквивалентно текущему значению переменной домена SX, а значение атрибута Д# эквивалентно текущему значению переменной домена PX.
В следующих примерах будем подразумевать существование следующих переменных доменов: SX (домен П#), PX (домен Д#), NAMEX (домен Имя). Переменные доменов объявляются каким-либо образом, подобно оператору RANGE исчисления кортежей.
Пример 5. Выражения исчисления доменов.
(SX) WHERE S (П#:SX)
(SX) WHERE S (П#:SX, Город_П: ‘Москва’)
NAMEX WHERE EXISTS SX (S(П#:SX, Имя: NAMEX)
AND FORALL PX (IF P (Д#:PX)
THEN SP (П#:SX, Д#:PX)))
Первое выражение означает множество всех номеров поставщиков отношения S, второе – множество номеров поставщиков из Москвы. Третье выражение соответствует запросу на получение имени поставщиков, производящих все детали.