«Boston • San Francisco • New York London • Toronto • Sydney • Tokyo • Singapore • Madrid Mexico City • Munich • Paris • Cape Town • Hong Kong • Montreal Введение в системы баз данных К. Дж. Дейт Москва • Санкт-Петербург ...»
TIMESTAMP
NUMERIC (p,q)INTERVAL
DECIMAL (p,q) Поддерживаются многочисленные применяемые по умолчанию параметры, сокращения и альтернативные имена, например, CHAR как сокращение от CHARACTER,CLOB— ОТ CHARACTER LARGE OBJECT, BLOB— ОТ BINARY LARGE OBJECT И
Т.Д.; В данной книге эти подробности не рассматриваются. Ниже приведена наиболее важная информация по этой теме.1. Встроенные типы данных BIT И BIT VARYING были введены в спецификации SQL: 1992 и должны быть снова изъяты из спецификации SQL:2003 (!).
2. Несмотря на их имена, содержащие слово "объект", типы CLOB и BLOB фактиче ски являются строковыми (они не имеют никакого отношения к объектам в том смысле, какой рассматривается в главе 25; в частности, тип BLOB фактически представляет собой строковый тип, состоящий из байтов или "октетов" (он не имеет ничего общего с двоичными числами, хотя и содержит в своем полном име ни слово BINARY). Кроме того, поскольку значения этих типов могут быть очень велики (поэтому такие значения иногда неформально называют просто длинными строками), в языке SQL предусмотрена конструкция, называемая локатором (locator), которая (кроме всего прочего) позволяет обеспечить доступ к отдельным фрагментам этих значений.
3. Для всех этих типов предусмотрены операторы присваивания и сравнения на ра венство. Операция сравнения на равенство по сути выполняется очень просто (но см. пункт 5). Оператор присваивания выглядит примерно следующим образом.
Безусловно, операции присваивания осуществляются также неявно при выполнении операций выборки и обновления базы данных. Но реляционное присваивание как таковое не поддерживается. Кроме того, не поддерживается множественное присваивание, за исключением следующего случая": если строка г обновляется с помощью оператора в приведенной ниже форме.
UPDATE T SET C1 = exp1,..., Cn = expn WHERE p ;
Здесь все выражения expl,..., expn вычисляются до того, как происходит любое из отдельных присваиваний переменным С1,..., Cn (a r представляет собой строку в результатах вычисления выражения т WHERE p).
4. Поддерживается строгая типизация, но только в ограниченном объеме. Точнее, к встроенным типам можно применить определенный способ классификации, согласно которому они подразделяются на 10 отдельных категорий следующим истинностное значение дата двоичное значение временная отметка символьная строка интервал год/месяц числовое значение интервал сутки/время суток Еще два исключения кратко описаны в главе 9, раздел 9.12, подраздел "Ограничения базовой таблицы" и в главе 10, раздел 10.6, подраздел "Обновления представлений". Если не считать этих исключений, автору не известно ни об одном программном продукте, представленном на современном рынке, который поддерживал бы множественное присваивание. Но автор считает, что такая поддержка желательна и даже необходима; и действительно, она запланирована для включения в спецификацию SQL:2003, но не для отношений.
188 Часть II. Реляционная модель Проверка типов происходит на основе именно таких 10 категорий (это особенно касается операций присваивания и проверки на равенство). Поэтому, например, попытка сравнить число и символьную строку является недопустимой, но попытка сравнить два числа осуществима, даже если эти числа относятся к разным числовым типам, скажем INTEGER и FLOAT (в данном примере перед выполнением сравнения значение INTEGER будет приведено к типу FLOAT).
5. Правила проверки типов являются особенно сложными применительно к символьным строковым типам, таким как CHAR (n), CHAR VARYING (П) И CLOB (n).
Изложение подробных сведений по этой теме выходит за рамки данной книги, но мы должны кратко рассмотреть случай символьных строк фиксированной длины (т.е. тип CHAR (п)), как описано ниже.
Сравнение. Если сравниваются значения типа CHAR (nl) и CHAR (n2), то более короткое значение обязательно дополняется справа пробелами так, чтобы его длина стала равной длине более длинного значения, и после этого происходит сравнение12. Поэтому, например, строки ' Р2 ' (с длиной два) и ' Р2 ' (с дли ной три) рассматриваются при их сравнении как равные.
Присваивание. Если значение типа CHAR(nl) присваивается переменной типа CHAR(n2), то перед выполнением операции присваивания значение CHAR(nl) дополняется справа пробелами при nl < п2 или усекается справа при nl > n2 для того, чтобы это значение могло иметь длину п2. Считается ошибкой, если при любом таком усечении теряются какие-либо непробельные Дополнительные пояснения и описания приведены в [4.20].
Типы DISTINCT Язык SQL поддерживает две разновидности определяемых пользователем типов — типы DISTINCT и структурированные типы; оба эти типа определяются13 с помощью оператора CREATE TYPE. Типы DISTINCT рассматриваются в этом подразделе, а структурированные типы — в следующем (ключевое слово "DISTINCT" записано здесь прописными буквами, чтобы подчеркнуть, что данное слово не используется в этом контексте в своем обычном естественном языковом смысле — как "различный"). Ниже приведено определение SQL для типа WEIGHT типа DISTINCT (сравните и сопоставьте всевозможные определения для этого типа на языке Tutorial D в разделе 5.4).
CREATE TYPE WEIGHT AS DECIMAL (5,1) FINAL ;
В своей простейшей форме (т.е. если не рассматриваются различные необязательные спецификации) это определение имеет следующий синтаксис.
Здесь предполагается, что к одному из сравниваемых операндов применяется операция дополне ния пробелами PAD SPACE [4.20].
Этот оператор поддерживает также некие конструкции, называемые в данном контексте доменами, но домены SQL не имеют ничего общего с доменами в реляционном смысле. Домены SQL подробно рассматриваются в [4.20].
CREATE TYPE AS FINAL ;
Ниже приведены дополнительные сведения по этой теме.1. Обязательная спецификация FINAL рассматривается в главе 20.
2. Параметр представляет собой имя другого типа (и этот рас сматриваемый тип не должен быть определен пользователем или сгенерирован).
В частности, следует отметить, что с учетом этих правил, касающихся применения параметра, мы не могли бы определить тип POINT из раздела 5.3 как тип DISTINCT языка SQL.
3. Следует также учитывать, что параметр задает не возможное представление, как было описано выше в этой главе, а скорее фактическое физи ческое представление рассматриваемого типа DISTINCT. В действительности, язык SQL вообще не поддерживает понятие "возможного представления possrep".
Одним из следствий такого упущения является то, что невозможно определить тип DISTINCT (или структурированный тип, когда речь пойдет о нем) с помощью двух или нескольких отдельных возможных представлений.
4. В языке SQL нет никаких конструкций, аналогичных спецификации CONSTRAINT языка Tutorial D. Например, в случае типа WEIGHT не существует способа, позво ляющего указать, что для каждого значения WEIGHT соответствующее значение DECIMAL ( 5, 1 ) должно быть больше нуля (чтобы вес не мог стать отрицатель ным!) или, скажем, меньше 5000.
5. Применимые к типу DISTINCT операторы сравнения определяются именно как такие операторы, которые могут применяться к соответствующему физическому представлению.
Примечание. Если не считать оператора присваивания (см. пункт 8), другие операторы, применимые к физическому представлению, не могут применяться к типу DISTINCT. Например, ни одно из следующих выражений не является допустимым, даже если WT относится к типу WEIGHT.
6. Селекторы и операторы ТНЕ_ поддерживаются. Например, если NW— переменная базового языка типа DECIMAL (5,1), то выражение WEIGHT ( :
NW) возвращает соответствующее значение веса, а если WT — столбец типа WEIGHT, то выражение DECIMAL(WT) возвращает 14 соответствующее значение DECIMAL(5,1 ). Поэтому следующие операции SQL являются допустимыми.
Фактически в синтаксисе, который определен в спецификации SQL: 1999, выражение DECIMAL (WT) не является допустимым, но предполагается, что оно станет допустимым в спецификации SQL:2003.
Однако следует отметить, что (в отличие от операторов ТНЕ_ языка Tutorial D) его нельзя будет использовать в качестве псевдопеременной.
190 Часть II. Реляционная модель
DELETE FROM P WHERE WEIGHT =
WEIGHT ( 14.7 ) ;
EXEC SQL DELETE FROM P WHERE WEIGHT
EXEC SQL DECLARE Z CURSOR FOR
SELECT DECIMAL ( WEIGHT ) AS DWT
7. За одним важным исключением (см. пункт 8), к типам DISTINCT применяются правила строгой типизации. Необходимо обратить особое внимание на то, что операции сравнения значений типа DISTINCT и значений типа, лежащего в основе представления типа DISTINCT, ЯВЛЯЮТСЯ недопустимыми. Поэтому следующие операторы SQL не считаются допустимыми, даже несмотря на то, что переменная NW (как и прежде) относится к типу DECIMAL ( 5, 1 ).недопустимый оператор!!! */ недопустимый оператор!!! */
EXEC SQL DECLARE Z CURSOR FOR
SELECT DECIMAL ( WEIGHT ) AS DWT
WHERE WEIGHT > :NW ; /* Предостережение: недопустимый 8. Исключение, упомянутое в пункте 7, касается операций присваивания. Например, если требуется выполнить выборку некоторого значения WEIGHT В определенную переменную типа DECIMAL( 5, 1), то должно быть выполнено преобразование типов. Безусловно, что такое преобразование может быть выполнено явно, как показано ниже.
SELECT DECIMAL ( WEIGHT ) AS DWT
INTO :NW FROM P WHERE P# = P# ('P1') ;Но следующий оператор также является допустимым (и при его выполнении происходит соответствующее приведение типа).
SELECT WEIGHT
INTO :NW FROM P WHERE P# = P# ('P1') ;Аналогичные замечания относятся к операциям INSERT и UPDATE.
9. Для преобразования в типы, из типов или между типами DISTINCT могут быть также явно определены операторы CAST. Подробные сведения об этом здесь не рассматриваются.
10. В случае необходимости могут быть определены дополнительные операторы (а в последующем они могут быть уничтожены).
Примечание. В языке SQL операторы называются программными модулями и подразделяются на три типа: функции, процедуры и методы. (Функции и процедуры могут рассматриваться в определенной степени как аналогичные описанным выше операторам, предназначенным только для чтения, и операторам обновления, соответственно; методы действуют подобно функциям, но вызываются15 с использованием другого синтаксического стиля.) Поэтому мы можем определить функцию (по сути представляющую собой полиморфную функцию), называемую ADDWT (сокращение от "add weight" — сложение весов), которая позволяет складывать два значения независимо от того, являются ли они значениями типа WEIGHT, или значениями типа DECIMAL( 5, 1), или сочетанием того и другого.
В таком случае все приведенные ниже выражения становятся допустимыми.
ADDWT ( WT, 14.7 ) ADDWT ( 14.7, WT ) ADDWT ( WT, WT ) ADDWT ( 14.7, 3.0 ) Дополнительную информацию, касающуюся программных модулей SQL, можно найти в [4.20] и [4.28]. Более подробные сведения о них выходят за рамки данной 11. Для уничтожения определяемого пользователем типа используется следующий Здесь параметр с обозначением способа выполнения может иметь значение RESTRICT ИЛИ CASCADE; неформально RESTRICT означает, что операция DROP должна окончиться неудачей, если данный тип в настоящее время где-либо используется в базе данных, а ключевое слово CASCADE означает, что операция DROP всегда оканчивается успешно и вызывает неявное применение операций DROP...CASCADE ко всем объектам, в которых в настоящее время используется этот тип (именно так!).
Структурированные типы Перейдем к изучению структурированных типов Ниже приведен ряд примеров.
CREATE TYPE POINT AS ( X FLOAT, Y FLOAT ) NOT FINAL ;
CREATE TYPE LINESEG AS ( BEGIN POINT, END POINT ) NOT FINAL }_
Кроме того, для методов, в отличие от функций и процедур, предусматривается определенное связывание во время прогона (см. главу 20).Примечание. Термин метод и немного странный смысл, который должен быть предписан ему в контекстах, подобных рассматриваемому в данном разделе, происходят из области объектно-ориентированных средств (см. главу 25).
192 Часть II. Реляционная модель (В действительности попытка выполнить второй оператор окончится неудачей, поскольку BEGIN и END в языке SQL являются зарезервированными словами, но автор ввел эти идентификаторы просто для удобства.) Поэтому в своей простейшей форме (т.е. если не рассматриваются различные необязательные спецификации) оператор создания структурированного типа имеет следующий синтаксис.
CREATE TYPE AS NOT FINAL ;
Ниже приведены дополнительные пояснения.1. Обязательная спецификация NOT FINAL рассматривается в главе 20.
Примечание. Предполагается, что в версии SQL:2003 вместо нее будет разрешено задавать альтернативную конструкцию FINAL.
2. Параметр представляет по своей структуре разделенный за пятыми список определений атрибутов, заключенный в круглые скобки; в этом списке параметр состоит из имени атрибута, за которым следует имя типа < type name>.
Но обратите особое внимание на то, что эти так называемые "атрибуты" не явля ются атрибутами в реляционном смысле, отчасти потому, что структурированные типы не являются реляционными типами (см. главу 6). Более того, применяемый здесь параметр представления обозначает фактическое фи зическое представление, а не просто некоторое возможное представление рас сматриваемого структурированного типа.
Примечание. Но проектировщик типа имеет возможность эффективно скрыть этот факт (т.е. действительно скрыть, что представление является физическим) благодаря продуманному выбору и тщательному проектированию операторов.
Например, если иметь в виду приведенное выше определение типа POINT, TO система автоматически предоставляет операторы для получения доступа к представлению точки в виде декартовых координат (см. пункты 3 и 6), но проектировщик типа может "вручную" предоставить операторы для получения доступа также и к представлению в виде полярных координат.
3. Каждое определение атрибута вызывает автоматическое определение двух соответ ствующих операторов (по сути аналогичных "методам"), причем один из них яв ляется наблюдателем (observer) и один — модификатором (mutator), которые пре доставляют функциональные возможности, аналогичные16 операторам ТНЕ_ языка Tutorial D. Например, если переменные LS, Р и z, соответственно, относятся к ти пам LINESEG, POINT и FLOAT, то следующие операторы присваивания являются допустимыми.
Ради достижения максимальной точности следует отметить, что в языке SQL модификаторы не являются в действительности модификаторами в обычном смысле этого термина (т.е. они не являются операторами обновления), но могут использоваться таким образом, чтобы с их помощью предоставлялись обычные функциональные средства модификаторов. Например, оператор "SET Р. Х = Z" (который фактически не содержит явного вызова модификатора!) определен как сокращенный вариант оператора "SET P = P. X ( Z ) " (который содержит такой вызов).
/* Действует как наблюдатель применительно к атрибуту X переменной Р /* Действует как модификатор применительно к атрибуту X переменной Р */ /* Действует как наблюдатель применительно к атрибуту BEGIN переменной LS */ SET X = LS.BEGIN.X ;
SET LS.BEGIN.X = Z ;
4. В рассматриваемом операторе не предусмотрена какая-либо конструкция, анало гичная спецификации CONSTRAINT языка Tutorial D.
5. Операторы сравнения, которые могут применяться к определяемым структуриро ванным типам, задаются с помощью отдельного оператора CREATE ORDERING.
Ниже приведены два примера.
CREATE ORDERING FOR POINT EQUALS ONLY BY STATE
; CREATE ORDERING FOR LINESEG EQUALS ONLY BY
Ключевые слова EQUALS ONLY означают, что для значений рассматриваемого типа единственными допустимыми операторами сравнения являются "=" и "/=" (или, скорее, "о", поскольку в языке SQL для обозначения операции сравнения на неравенство используется именно такой знак операции). Ключевые слова BY STATE указывают, что два значения рассматриваемого типа являются равными, если и только если их i-e атрибуты равны при всех значениях i. Описание других возможных спецификаций CREATE ORDERING выходит за рамки данной книги;достаточно сказать, что, например, при желании для структурированного типа может быть также определена семантика оператора ">". Но следует отметить, что если данный структурированный тип не имеет связанного с ним "упорядочения", то со значениями этого типа не могут выполняться никакие операции сравнения, даже сравнения на равенство; вполне очевидно, что такое состояние дел имеет далеко идущие последствия.
6. Ни один из селекторов не предоставляется автоматически, но эффект, аналогичный действию этих операторов, может быть достигнут следующим образом. Прежде всего, язык SQL автоматически предоставляет то, что именуется в нем функциямиконструкторами (constructor function), но такие функции при каждом вызове возвращают одно и то же значение, а именно то значение рассматриваемого типа, все атрибуты которого имеют применимое заданное по умолчанию значение17.
Например, при следующем вызове функции-конструктора POINT () Применяемое по умолчанию значение для определенного атрибута можно указать в составе соответствующего определения атрибута. Если ни одно подобное значение не указано явно, то применяемое по умолчанию значение (своего рода "значение, заданное по умолчанию для использования по умолчанию") будет пустым.
Примечание. По причинам, которые не рассматриваются в этой книге, применяемое по умолчанию значение обязательно должно быть пустым, если типом атрибута является либо тип строки таблицы, либо определяемый пользователем тип (такой как POINT), и он обязательно должен быть задан либо с помощью пустого значения, либо пустого массива (обозначенного как ARRAY [ ]), если это - тип массива. Поэтому, например, вызов функцииконструктора LINESEG () должен обязательно возвратить отрезок прямой, оба компонента которого, BEGIN и END, ДОЛЖНЫ быть пустыми.
194 Часть II. Реляционная модель возвращается точка с заданными по умолчанию значениями у и X. Но после этого сразу же появляется возможность вызывать модификаторы X и Y (см. пункт 3) для получения любой такой точки, которая должна быть определена с помощью результатов этого вызова функции-конструктора. Более того, существует возможность связать первоначальную операцию "конструирования" и последующую операцию "модификации" в одно выражение, как показано в следующем примере.
Ниже приведен более сложный пример.
LINESEG (). BEGIN ( POINT () Примечание. При желании перед вызовами функции-конструктора можно ставить необязательное ключевое слово NEW без изменения их семантики, например, следующим образом.
NEW LINESEG (). BEGIN ( NEW POINT 7. К структурированным типам применяются правила строгой типизации, за исключением, возможно, тех случаев, которые описаны в главе 6, раздел 6.6 (подраздел "Структурированные типы").
8. Кроме уже упомянутых операторов, в случае необходимости могут быть определе ны (а в последующем могут быть удалены) дополнительные операторы.
9. Предусмотрена возможность удаления структурированных типов и упорядочений ORDERING. Кроме того, предусмотрена возможность "изменять" определения та ких типов с помощью оператора ALTER TYPE, например, можно добавлять новые атрибуты или удалять существующие (иными словами, изменять представление Дополнительная информация о структурированных типах SQL приведена в следующей главе (раздел 6.6), а также в главах 20 и 26.
Генераторы типов В языке SQL поддерживаются три генератора типов18 (в терминологии SQL они называются конструкторами типов): REF, ROW и ARRAY. В данной главе рассматриваются только ROW и ARRAY, а описание REF откладывается до главы 26. Ниже приведен пример, иллюстрирующий использование генератора типа строки ROW.
CREATE TABLE CUST
ADDR ROW ( STREET CHAR(50), CITY CHAR(25), STATE CHAR(2), ZIP CHAR(5) ) PRIMARY KEY ( CUST# ) ) ;Существует вероятность того, что в версии SQL:2003 будет введен еще один генератор типа MULTISET.
Здесь STREET, CITY, STATE и ZIP— поля сгенерированного строкового типа. В общем, такие поля могут иметь любой тип, включая другие строковые типы. В ссылках на уровни поля используется способ уточнения с помощью точки, как в следующем примере (в нем применяется синтаксис.< field name>, где выражение должно иметь значение строкового типа).
SELECT CX.CUST# FROM
CUST AS CX WHERE
CX.ADDR.STATE = 'СA' ;Примечание. Здесь CX — имя корреляции. Имена корреляций подробно рассматриваются в главе 8 (раздел 8.6), а пока просто отметим, что язык SQL требует использования явных имен корреляций в ссылках на имена полей для того, чтобы можно было избежать определенной синтаксической неоднозначности, которая могла бы возникнуть в ином случае.
А ниже приведен пример оператора INSERT.
INSERT INTO CUST ( CUST#, ADDR ) VALUES ( ' 666 ', ROW ( '1600 Pennsylvania Ave.', Обратите внимание на использование в данном примере "литерала строки" (фактически он должен был бы называться "литералом строки" и поэтому заключен в кавычки, но формально в языке SQL нет такого понятия, как литерам строки, и выражение, применяемое в данном примере, представляет собой конструктор значения строки).
Ниже приведен еще один пример.
UPDATE CUST AS CX
SET CX.ADDR.STATE = 'TX' WHERE CUST# = '999 ' ;Примечание. Фактически в стандарте в настоящее время не допускается обновление на уровне поля, как в этом примере, но это упущение можно считать просто недосмотром, который обязательно должен быть устранен.
Генератор типа ARRAY является во многом аналогичным. Ниже приведен соответствующий пример.
CREATE TABLE
SALES INTEGER ARRAY
196 Часть II. Реляционная модель Типы, сгенерированные с помощью генератора типа ARRAY, всегда являются одномерными; в качестве заданного типа элемента (в данном примере INTEGER) можно использовать все, что угодно, кроме еще одного типа массива19. Допустим, что а — значение некоторого типа массива. В таком случае а может содержать любое количество п элементов (п > 0) вплоть до, но не больше указанной верхней границы (в данном примере 12). Если а содержит точно п элементов (п > 0), то этими элементами являются именно а [ 1 ], а [ 2 ],..., а [ п ], и н а них можно ссылаться именно таким образом. Выражение CARDINALITY (а) возвращает значение п.Ниже приведены некоторые примеры, в которых используется таблица ITEM_SALES.
Обратите внимание на то, что во втором примере применяется литерал массива (или, скорее, "литерал массива", в кавычках, поскольку формально он называется конструктором значения массива).
SELECT ITEM#
FROM ITEM_SALES
WHERE SALES [3] > 10 ;
INSERT INTO ITEM_SALES ( ITEM#, SALES
) VALUES ( 'X4320',UPDATE ITEM_SALES SET
SALES [3] = 10 WHERE ITEM# = 'Z0564' ;Завершаем этот раздел замечанием, что к типам ROW и ARRAY применимы операторы присваивания и сравнения на равенство, при условии, что операторы присваивания и сравнения на равенство применимы к типам элементов рассматриваемого типа ROW ИЛИ ARRAY; если же последние операторы не определены, то нельзя определить и соответствующие операторы для рассматриваемого типа ROW или ARRAY.
5.8. РЕЗЮМЕ В данной главе приведено всестороннее описание важного понятия типов данных (называемых также доменами или просто типами). Тип представляет собой множество значений, а именно, множество всех значений, которые соответствуют некоторому ограничению типа (определяемому в языке Tutorial D с помощью конструкции POSSREP, включающей необязательную спецификацию CONSTRAINT). Каждый тип имеет связанное с ним множество операторов (к нему относятся и операторы, предназначенные только для чтения, и операторы обновления), позволяющие оперировать со значениями и переменными рассматриваемого типа. Типы могут быть сколь угодно простыми или Существует вероятность того, что это ограничение в версии SQL:2003 будет снято. В любом случае, типом элемента может быть тип строки, а этот тип строки может включать поле некоторого типа массива.
Поэтому (например) ниже приведено допустимое определение переменной.
VX ROW (FX INTEGER ARRAY [ 1 2 ] ) ARRAY [12] И в таком случае (например) VX [ 3 ]. FX [ 5 ] ссылается на пятый элемент массива, который представляет собой единственное значение поля в строке, которая является третьим элементом массива, представляющим собой значение переменной VX.
сложными, поэтому могут быть предусмотрены типы, значениями которых являются числа, строки, даты, отметки времени, звукозаписи, географические карты, видеозаписи или геометрические точки и т.д. Допустимое множество операторов зависит от типов в том смысле, что операнды любой конкретной операции обязательно должны иметь тип, определенный для этой операции (строгая типизация). Строгая типизация весьма желательна, поскольку она позволяет своевременно выявлять определенные логические ошибки, которые к тому же обнаруживаются на этапе компиляции, а не на этапе прогона. Следует отметить, что применение строгой типизации влечет за собой особо важные последствия по отношению к реляционным операциям (соединение, объединение и т.д.), как будет описано в главе 7.
Кроме того, в этой главе рассматривалось важное логическое различие между значениями и переменными и было указано, что существенным свойством значения является то, что его нельзя обновлять. Значения и переменные всегда являются типизированными;
таковыми являются также (реляционные) атрибуты, (предназначенные только для чтения) операторы, параметры и, вообще говоря, выражения произвольной сложности.
Типы могут быть определяемыми системой или пользователем; кроме того, они могут быть скалярными или нескалярными. Скалярный тип не имеет компонентов, видимых пользователю. (Наиболее важными нескалярными типами в реляционной модели являются типы отношения, которые рассматриваются в следующей главе.) Автор стремится показать важное различие между типом и его физическим представлением (типы относятся к уровню модели, а физические представления — к уровню реализации). Но требуется также, чтобы каждый тип имел по меньшей мере одно объявленное возможное представление (допустимо также наличие больше одного такого представления). Каждое подобное возможное представление вызывает автоматическое определение одного оператора селектора, а также определение по одному оператору ТНЕ_ для каждого компонента этого возможного представления (включая псевдопеременную ТНЕ_). Автор поддерживает идею явного преобразования типов, но не поддерживает неявные способы приведения типов.
Автор является также сторонником подхода, предусматривающего определение любого количества дополнительных операторов для скалярных типов, и выдвигает требование, чтобы для каждого типа был предусмотрен оператор сравнения на равенство и оператор присваивания (возможно, даже множественного).
В настоящей главе рассматривались также генераторы типов, представляющие собой операторы, которые возвращают типы (такие как ARRAY). Ограничения и операторы, применимые к сгенерированным типам, происходят от универсальных ограничений и операторов, которые связаны с применимым генератором типа.
Наконец, в этой главе были кратко описаны средства определения типов языка SQL.
В языке SQL предусмотрен целый ряд встроенных типов, таких как BOOLEAN, INTEGER, DATE, TIME и т.д. (с каждым из которых, безусловно, связано определенное множество операторов), но в связи с этим типами поддерживается лишь ограниченная форма строгой типизации. Этот язык позволяет также пользователям определять свои собственные типы, которые подразделяются на типы DISTINCT И структурированные типы; кроме того, он поддерживает некоторые генераторы типов (ARRAY и ROW, а также REF). В настоящей главе приведен анализ всех этих функциональных средств SQL с точки зрения тех идей, которые были представлены в ней выше.
198 Часть II. Реляционная модель
УПРАЖНЕНИЯ
5.1.Сформулируйте правила определения типов для операторов присваивания (":=") и сравнения на равенство ("=").5.2.Покажите, в чем состоят различия:
значения и переменной;
типа и представления;
физического представления и возможного представления;
скалярной и нескалярной переменной;
оператора, предназначенного только для чтения, и оператора обновления.
5.3.Дайте своими словами определения следующих терминов:
генератор типа литерал оператор ТНЕ_ перечислимый тип полиморфная операция приведение типа псевдопеременная сгенерированный тип селектор строгий контроль типов 5.4.Почему с формальной точки зрения псевдопеременные не являются строго необходимыми?
5.5.Определите оператор, который, получив в качестве параметра рациональное число, возвращает куб этого числа.
5.6.Определите оператор, предназначенный только для чтения, который, получив в качестве параметра точку с декартовыми координатами х и у, возвращает точку с декартовыми координатами f(x) и g (у), где f и g — заранее определенные операторы.
5.7.Повторите упр. 5.6, но примените вместо оператора, предназначенного только для чтения, оператор обновления.
5.8.Дайте определение типа для скалярного типа CIRCLE. Какие селекторы и операторы ТНЕ_ применимы к этому типу? Кроме этого, выполните перечисленные ниже задания.
а) Определите множество операторов, предназначенных только для чтения, которые позволяют определить диаметр, периметр и площадь данного круга.
б) Определите оператор обновления, позволяющий удвоить радиус данного круга (точнее, модифицировать заданную переменную CIRCLE таким образом, чтобы представленные с ее помощью параметры круга оставались неизменными, за исключением радиуса, — его новое значение должно увеличиваться вдвое по сравнению с предыдущим).
5.9.Приведите некоторые примеры типов, для которых было бы удобно определить два или больше различных возможных представлений. Если возможно, приведите такой пример, в котором различные возможные представления для одного и того же типа имеют разное количество компонентов.
5.10.Рассмотрим каталог для базы данных отделов и служащих, схематически показанный на рис. 3.6 в главе 3. Как можно расширить этот каталог, чтобы в нем учитывались определяемые пользователем типы и операторы?
5.11.На основе каких типов определены переменные отношения самого каталога?
5.12.Приведите соответствующее множество определений скалярных типов для базы данных деталей, поставщиков и проектов (см. рис. 4.5 на стр. 154). Выполните это упражнение, не предпринимая попыток предварительно записать определения переменной отношения.
5.13.Как было указано в разделе 5.3, строго говоря, недопустимо использовать такую формулировку, что (например) количество предметов в некоторой поставке равно 100. ("Количество— это значение типа QTY, а не значение типа INTEGER!").
Вследствие этого рис. 4.5 является довольно сомнительным, поскольку он наводит на мысль, что, например, значения количества могут рассматриваться как целые числа. С учетом полученного вами ответа на упр. 5.12, покажите правильный способ задания различных скалярных значений на рис. 4.5.
5.14.С учетом полученного вами ответа на упр. 5.12, укажите, какие из следующих скалярных выражений являются допустимыми. Для допустимых выражений укажите тип результата, а для недопустимых составьте соответствующее допустимое выражение, позволяющее получить результат, который, по-видимому, должен быть достигнут в данном случае.
а) J.CITY = P. CITY.
б) JNAME | | PNAME.
в) QTY * 100.
Г) QTY + 100.
Д) STATUS + 5.
е) J.CITY < S.CITY.
Ж) COLOR = P. CITY.
3) J.CITY = P. CITY | | 'burg'.
5.15.Иногда можно встретить такие утверждения, что типы в действительности также являются переменными, как и переменные отношения. Например, может потребоваться увеличить количество знаков в представлении табельных номеров с трех цифр до четырех в связи с увеличением количества служащих на предприятии.
Тогда соответствующую операцию можно было бы назвать обновлением типа "множества всех возможных табельных номеров". Изложите свое мнение по поводу таких утверждений.
200 Часть II. Реляционная модель 5.16.Приведите аналоги всех определений типов, приведенных в разделах 5.3 и 5.4, в контексте языка SQL.
5.17.Приведите ответ к упр. 5.12 на языке SQL.
5.18.В контексте языка SQL ответьте на следующие вопросы.
а) Что такое тип DISTINCT? Какое общее название применяется к значениям типа DISTINCT? Может ли существовать тип, отличный от DISTINCT?
б) Что такое структурированный тип? Какое общее название применяется к значениям структурированного типа? Может ли существовать тип, отличный от структурированного?
5.19.Дайте определения терминов наблюдатель, модификатор и функция-конструктор, которые используются в языке SQL.
5.20.Каковыми будут последствия того, что для некоторого конкретного типа не будет определен оператор "="?
5.21.Тип — это множество значений, поэтому может быть определен пустой тип, представляющий собой (обязательно уникальный) тип, в котором рассматриваемое множество является пустым. Укажите возможные области применения такого типа.
5.22.Строго говоря, в языке SQL отсутствуют литералы строк или массивов. Объясните смысл этого утверждения и обоснуйте его.
5.23.Рассмотрите тип POINT языка SQL, который определен в подразделе "Структурированные типы" раздела 5.7. Этот тип имеет представление, в котором используются декартовы координаты X и Y. Что произойдет, если этот тип будет заменен пересмотренным типом POINT, имеющим представление, в котором вместо этого используются полярные координаты R и 6?
5.24.В чем состоит различие между операторами CARDINALITY и COUNT языка SQL?
Примечание. Оператор COUNT рассматривается в разделе 8.6 главы 8.
СПИСОК ЛИТЕРАТУРЫ
5.1. Cleaveland J.C. An Introduction to Data Types // Reading, Mass.: Addison-Wesley, 6.1. Введение 6.3. Типы отношений 6.4. Значения отношений 6.5. Переменные отношения 6.6. Средства SQL В предыдущей главе в целом рассматривались типы, значения и переменные, а в этой главе приведены конкретные сведения о типах, значениях и переменных отношения. Кроме того, поскольку отношения формируются из кортежей (выражаясь довольно неформально), необходимо также рассмотреть типы, значения и переменные кортежей. Но следует сразу же отметить, что кортежи сами по себе не являются столь важными, по крайней мере, с точки зрения реляционной теории; их значимость обусловлена прежде всего тем фактом, что они представляют собой промежуточную ступень на пути к отношениям.Вначале рассмотрим точное определение термина кортеж. Если дана коллекция типов Ti (i = 1, 2,..., п), которые не обязательно все должны быть разными, то значением кортежа (или кратко кортежем), определенным с помощью этих типов (назовем его t), является множество упорядоченных троек в форме, где Ai — имя атрибута, Ti — имя типа и vi — значение типа Ti. Кроме того, кортеж t должен соответствовать приведенным ниже требованиям.
202 Часть II Реляционная модель Значение п имеет степень, или арность t.
Упорядоченная тройка является компонентом t.
Упорядоченная пара представляет собой атрибут t и однозначно опреде ляется именем атрибута Ai (имена атрибутов Ai и Aj совпадают, только если i=j).
Значение vi — это значение атрибута, соответствующее атрибуту1 Ai кортежа t.
Тип Ti — это соответствующий тип атрибута.
Полное множество атрибутов составляет заголовок t.
Тип кортежа t определен заголовком t, а сам заголовок и этот тип кортежа имеют такие же атрибуты (и поэтому такие же имена и типы атрибутов) и такую же сте пень, как t. Ниже показано точное определение имени типа кортежа.
А ниже показан пример кортежа.
В этом кортеже атрибуты имеют имена MAJOR_P#, MINOR_P# и QTY; соответствующими именами типов являются: р#, еще один экземпляр р# и QTY, а соответствующими значениями — Р# { ' Р2 '), Р# ( ' Р4 ' ) и QTY (7) (для упрощения в этой таблице указанные значения были заменены, соответственно, сокращенными обозначениями Р2, Р4 и 7).
Приведенный выше кортеж имеет степень три, а его заголовок имеет следующий вид.
Ниже приведено определение типа этого кортежа.
TUPLE { MAJOR_P# P#, MINOR_P# P#, QTY QTY } Примечание. В неформальном изложении принято исключать имена типов из заголовка кортежа и показывать только имена атрибутов. Поэтому показанный выше кортеж может быть неформально представлен следующим образом.
В языке Tutorial D для обозначения рассматриваемого кортежа может использоваться следующее выражение.
TUPLE { MAJOR_P# Р#('Р2'), MINOR_P# Р#('Р4'), QTY QTY(7) } (Это выражение может служить примером вызова селектора кортежа; см. раздел "Генератор типа TUPLE".) В данном выражении заслуживает особого внимания то, что Безусловно, существует логическое различие между именем атрибута и атрибутом как таковым.
Но несмотря на этот факт, в неформальном общении часто используется выражения типа "атрибут Ai" для обозначения атрибута, имеющего имя Ai (в действительности подобные выражения уже встречались несколько раз в предыдущей главе).
типы атрибутов кортежа определены однозначно с использованием заданных значений атрибутов (например, атрибут MINOR_P# ОТНОСИТСЯ К типу р#, поскольку к типу Р# относится соответствующее значение атрибута).
Свойства кортежей Для описания кортежей используется целый ряд важных свойств, которые являются непосредственным следствием определений, приведенных выше в данном разделе. Некоторые из этих свойств перечислены ниже.
Каждый кортеж содержит точно одно значение (соответствующего типа) для каж дого из своих атрибутов.
Для компонентов кортежа не предусмотрено упорядочение, допустим, слева на право. Это свойство следует из того, что понятие кортежа определено на основа нии множества компонентов, а в математике множества не характеризуются упо рядочением своих элементов.
Каждое подмножество кортежа представляет собой кортеж (а каждое подмножест во заголовка является заголовком). Более того, эти свойства являются истинными применительно, в частности, к пустым подмножествам! (см. следующий абзац).
Дополнительные определения. Кортеж степени один называется одноэлементным, кортеж степени два — двухэлементным, кортеж степени три — трехэлементным (и т.д.); в общем кортеж степени п называют n-элементным2. Кортеж нулевой степени (т.е. кортеж без компонентов) называют нуль-элементным или нуль-арным. Кратко проиллюстрируем последнее определение. Ниже приведен нуль-арный кортеж в системе обозначений языка Tutorial D.
Иногда для обозначения кортежа нулевой степени применяется более наглядное представление, такое как "0-элементный кортеж". Это позволяет подчеркнуть тот факт, что данный кортеж не имеет компонентов. На первый взгляд может показаться, что нульэлементные кортежи почти не имеют практического значения, но фактически оказывается, что это понятие является исключительно важным. Дополнительная информация по этой теме приведена в разделе 6.4.
Генератор типа TUPLE В языке Tutorial D предусмотрен генератор типа TUPLE, который может быть вызван в определении (например) некоторого атрибута переменной отношения или некоторой переменной кортежа3. Ниже приведен пример применения последнего варианта.
Вместо термина кортеж иногда используется термин n-элементный кортеж (и по этому принципу формируются, например, выражения четырехэлементный кортеж, двухэлементный кортеж и т.д.). Но обычно принято опускать прилагательное с обозначением количества элементов.
Переменные кортежа не входят в состав реляционной модели, поэтому их применение в реляцион ной базе данных не предусмотрено. Но такая система, которая полностью поддерживает реляционную модель, по-видимому, могла бы поддерживать возможность использования переменных кортежа в от дельных приложениях (т.е. переменные кортежа представляют собой понятия, "локальные по отноше нию к отдельным приложениям").
204 Часть II. Реляционная модель
VAR ADDR TUPLE { STREET
Вызов генератора типа TUPLE имеет следующую общую форму.Здесь каждый параметр с обозначением атрибута состоит из имени атрибута, за которым следует имя типа. Тип кортежа вырабатывается в результате конкретного вызова генератора типа TUPLE; например, тип, только что показанный в определении переменной ADDR, безусловно, является сгенерированным типом.
Каждый тип кортежа имеет связанный с ним оператор селектора кортежа. Ниже приведен пример вызова селектора для типа кортежа, показанного в определении переменной ADDR.
TUPLE { STREET ' 1 6 0 0 Pennsylvania A v e. ', CITY 'Washington', Кортеж, определяемый этим выражением, может быть присвоен переменной кортежа ADDR или проверен на равенство другому кортежу того же типа. В частности, следует отметить, что необходимым и достаточным условием того, чтобы два кортежа имели одинаковый тип, является наличие в них одинаковых атрибутов. Обратите также внимание на то, что сами атрибуты определенного типа кортежа могут относиться к любому типу (они могут даже принадлежать к некоторому типу отношения или некоторому другому типу кортежа).
Операции с кортежами Выше в данной главе уже кратко упоминались операции применения селектора кортежа, присваивания и проверки на равенство. А теперь необходимо подробно изучить смысл операции проверки кортежей на равенство, поскольку значительная часть материала, приведенного в следующих главах, основана на использовании таких операций.
А именно, в терминах этих операций определены все перечисленные далее понятия.
По сути, все операции реляционной алгебры (см. главу 7).
Потенциальные ключи (см. главу 9).
Внешние ключи (см. также главу 9).
Функциональные и другие зависимости (см. главы 11—13).
Кроме того, на этих операциях основаны определения многих других понятий. Ниже приведено точное определение операции проверки кортежей на равенство.
Операция проверки кортежа на равенство. Кортежи tl и t2 являются равными (т.е.
выражение tl = t2 принимает истинное значение) тогда и только тогда, когда они имеют одинаковые атрибуты А1, А2,..., An и для всех i (i = 1, 2,..., п) значение vl атрибута Ai в кортеже tl равно значению v2 атрибута Ai в Кроме того (это утверждение может показаться очевидным, но должно быть выражено явно), кортежи tl и t2 являются дубликатами по отношению друг к другу тогда и только тогда, когда они равны в указанном выше смысле (это означает, что они действительно ничем не отличаются друг от друга).
Следует отметить, что из приведенного выше определения непосредственно следует, что все нуль-элементные кортежи являются дубликатами друг друга! По этой причине мы имеем право непосредственно использовать термин нуль-элементный кортеж, как мы обычно и делаем (а не рассуждать о некотором нуль-элементном кортеже).
Следует также учитывать, что к кортежам не могут применяться операторы сравнения на неравенство, "" (т.е. типы кортежа не относятся к категории "порядковых типов").
В дополнение к сказанному выше, в [3.3] предложены аналоги некоторых широко известных реляционных операций (которые будут рассматриваться в главе 7) — проекция кортежа, соединение кортежей и т.д. Эти операции в основном не требуют объяснения, поэтому остановимся на том, что рассмотрим здесь только один пример — проекцию кортежа (эта операция, вероятно, имеет наибольшее практическое значение). Предположим, что переменная ADDR имеет определение, указанное в предыдущем подразделе, а ее текущее значение можно представить следующим образом.
TUPLE { STREET 1600 Pennsylvania Ave.', CITY 'Washington', STATE 'DC', ZIP '20500' } В этом случае проекция кортежа определяет следующий кортеж.
Нам необходимо также иметь возможность извлекать значение указанного атрибута из определенного кортежа. Например, если переменная ADDR определена, как указано выше, то выражение
ZIP FROM ADDR
позволяет получить следующее значение.'20500' Ссылка на тип кортежа Одним из важных преимуществ схемы именования типа кортежа, которая определена в начале данного раздела, является то, что она упрощает задачу выявления типа результата произвольного выражения с участием кортежа. Например, еще раз рассмотрим следующую проекцию кортежа.
Как уже было сказано, это выражение позволяет получить кортеж, образующийся из текущего значения ADDR путем "выделения проекции" по атрибутам STREET и STATE, a тип кортежа для этого производного кортежа имеет следующее точное определение.
TUPLE { CITY CHAR, ZIP CHAR } Аналогичные замечания относятся ко всем возможным выражениям с кортежами.
206 Часть II. Реляционная модель Операции WRAP и UNWRAP Рассмотрим следующие типы кортежей.
TUPLE { NAME NAME, ADDR TUPLE { STREET CHAR, CITY CHAR,
TUPLE { NAME NAME, STREET CHAR, CITY
CHAR, STATE CHAR, ZIP
В дальнейшем будем использовать для этих типов кортежей, соответственно, обозначения ТТ1 и ТТ2. Следует, в частности, отметить, что тип ТТ1 включает атрибут, который сам относится к определенному типу кортежа (но степень ТТ1 равна двум, а не пяти). Теперь предположим, что NADDR1 и NADDR2 — переменные кортежа типов ТТ1 и ТТ2, соответственно. В таком случае могут быть выполнены описанные ниже операции.Выражение NADDR2 WRAP { STREET, CITY, STATE, ZIP } AS ADDR принимает текущее значение переменной NADDR2 и сворачивает компоненты STREET, CITY, STATE и ZIP этого значения для получения компонента ADDR, значением которого является один кортеж. Поэтому результатом такого выражения является переменная типа ТТ1, и в связи с этим (например) следующий оператор присваивания становится допустимым.
NADDR1 := NADDR2 WRAP { STREET, CITY, STATE, ZIP } AS ADDR ;
Выражение
NADDRl UNWRAP ADDR
принимает текущее значение переменной NADDRl и разворачивает компоненты значения переменной ADDR (значением которой является кортеж) для получения четырех отдельных компонентов STREET, CITY, STATE и ZIP, поэтому результат данного выражения относится к типу ТТ2, и в связи с этим (например) следующий оператор присваивания становится допустимым.NADDR2 := NADDRl UNWRAP ADDR ;
Сравнение типов кортежей и возможных представлений Внимательный читатель мог заметить определенную аналогию между синтаксисом генератора типа TUPLE, который описан в этом разделе, и синтаксисом объявленного возможного представления, который рассматривается в главе 5 (в обоих синтаксических определениях используются разделенные запятыми списки элементов, а каждый элемент определяет имя некоторого объекта и имя соответствующего типа), поэтому у читателя может возникнуть вопрос о том, имеем ли мы дело с двумя понятиями или только с одним. В действительности это два отдельных понятия (и синтаксическое сходство определений не имеет значения). Например, если X относится к типу кортежа, то на практике вполне может потребоваться получить проекцию некоторого значения этого типа, как описано в предыдущем подразделе. Но если X — возможное представление для некоторого скалярного типа т, то задача получения проекции значения этого скалярного типа т не возникает. Дополнительные сведения по этой теме приведены в [3.3].
6.3. ТИПЫ ОТНОШЕНИЙ Теперь перейдем к изучению отношений. В этом описании часто будут рассматриваться аналогии с определениями, касающимися кортежей, которые были сформулированы в предыдущем разделе, но применительно к отношениям должно быть приведено намного больше информации по сравнению с кортежами, поэтому соответствующий материал был разбит на несколько разделов: в разделе 6.3 рассматриваются типы отношения, в разделе 6.4 — значения отношений, а в разделе 6.5 — переменные отношения (relation variable, или сокращенно relvar).
Вначале рассмотрим точное определение термина отношение. Значение отношения (или просто отношение), допустим г, состоит из заголовка и тела4, которые соответствуют определениям, приведенным ниже.
Заголовок отношения r представляет собой заголовок кортежа, определение кото рого приведено в разделе 6.2. Отношение r имеет такие же атрибуты (следова тельно, такие же имена и типы атрибутов) и такую же степень, как заголовок.
Тело отношения r представляет собой множество кортежей, имеющих один и тот же заголовок; кардинальность отношения r определяется как кардинальность этого множества. (Вообще говоря, кардинальностью множества называется коли чество элементов множества.) Тип отношения r определяется заголовком r и имеет такие же атрибуты (следовательно, имена и типы атрибутов) и степень, как и сам заголовок. Ниже приведено точное определение имени типа отношения.
А здесь показан пример отношения (он аналогичен, но не идентичен отношению, показанному на рис. 4.6 в главе 4).
Это отношение имеет следующий тип.
RELATION { MAJOR_P# P#, MINOR_P# P#, QTY QTY } Если рассматривается обычное изображение отношения в виде таблицы, то заголовок соответствует строке имен столбцов, а тело — множеству строк с данными. В литературе заголовок именуется также схемой (отношения) или иногда просто схемой. Кроме того, заголовок иногда называют содержанием (intension), и в таком случае для обозначения тела применяется термин расширение (extension).
208 Часть II. Реляционная модель В неформальном изложении принято исключать из заголовка отношения имена типов и показывать только имена атрибутов. Поэтому приведенное выше отношение можно неформально представить следующим образом.
В языке Tutorial D для обозначения этого отношения можно использовать следующее выражение.
TUPLE { MAJOR_P# Р#('P1'),MINOR_P# P#('P2'), QTY QTY(5) }, TUPLE { MAJOR_P# P#('P1'),MINOR_P# P#('P3'), QTY QTY(3) }, TUPLE { MAJOR_P# P#('P2'),MINOR_P# P#('P3'), QTY QTY(2) }, TUPLE { MAJOR_P# P#('P2'),MINOR_P# P#('P4'), QTY QTY(7) }, TUPLE { MAJOR_P# P#('P3'),MINOR_P# P#('P5'), QTY QTY(4) }, Это выражение представляет собой пример вызова селектора отношения, который имеет следующий общий формат.
Здесь необязательный параметр, представляющий собой разделенный запятыми список атрибутов, заключенный в фигурные скобки, требуется, только если не задан параметр с обозначением списка выражении кортежа < tuple exp coimalist>. Безусловно, все выражения кортежа < tuple exp> должны относиться к одному и тому же типу кортежа, а этот тип кортежа должен быть точно таким же, как и тот, который определен параметром, если задан этот параметр.
Следует отметить что отношение, строго говоря, не содержит кортежей - оно содержит тело а тело в свою очередь включает в себя кортежи. Но при неформальном общении удобно формулировать свои высказывания так, как если бы отношения непосредственно включали кортежи, и мы во всей этой книге будем следовать этим соглашениям, позволяющим упростить изложение материала.
Как и в случае кортежей, отношение степени один называется унарным, отношение степени два - бинарным, отношение степени три - тернарным (и т.д.); в общем, отношение степени п называется п-арным. Отношение нулевой степени (т.е. отношение без атрибутов) принято называть нуль-арным (последний вариант отношения подробно рассматривается в следующем разделе). Кроме того, следует отметить, что справедливы приведенные ниже утверждения.
Каждое подмножество заголовка является заголовком (как и в случае кортежей).
Каждое подмножество тела является телом.
В обоих случаях рассматриваемое подмножество может, в частности, быть пустым подмножеством.
Генератор типа RELATION В языке Tutorial D предусмотрен генератор типа RELATION, который может быть вызван (например) в определении некоторой переменной отношения. Соответствующий пример приведен ниже.
VAR PART_STRUCTURE...
RELATION { MAJOR_P# P#, MINOR_P# P#, QTY QTY }... ;
(Здесь для упрощения исключены те части определения, которые не относятся к данной теме.) В общем, генератор типа RELATION имеет такую же форму, как и генератор типа TUPLE, за исключением того, что вместо ключевого слова TUPLE применяется ключевое слово RELATION. Тип отношения, выработанный в результате конкретного вызова генератора типа RELATION (например, только что показанный в определении переменной отношения PART_STRUCTURE), безусловно, является сгенерированным типом.
Каждый тип отношения имеет соответствующий оператор селектора отношения.
Выше уже был приведен пример вызова селектора для только что показанного типа отношения. Отношение, полученное с помощью этого вызова селектора, может быть присвоено переменной отношения PART_STRUCTURE или проверено на равенство с другим отношением такого же типа. В частности, следует отметить, что необходимым и достаточным условием того, чтобы два отношения принадлежали к одному и тому же типу, является наличие в них одинаковых атрибутов. Необходимо также учитывать, что атрибуты любого заданного типа отношения сами могут принадлежать к любому типу (они могут даже принадлежать к некоторому типу кортежа или к некоторому другому типу отношения).
6.4. ЗНАЧЕНИЯ ОТНОШЕНИЙ В этом разделе мы приступим к более подробному изучению отношений (т.е. значений отношений) как таковых. Прежде всего, необходимо отметить, что отношения обладают определенными свойствами; все эти свойства непосредственно следуют из определения отношения, приведенного в предыдущем разделе, и все они являются очень важными. Вначале сформулируем рассматриваемые свойства, а затем подробно их опишем.
Любое конкретное отношение обладает свойствами, указанными ниже.
1. Каждый кортеж содержит точно одно значение (соответствующего типа) для каж дого атрибута.
2. Атрибуты не характеризуются каким-либо упорядочением (например, слева на 3. Кортежи не характеризуются каким-либо упорядочением (например, сверху вниз).
4. В отношении отсутствуют дубликаты кортежей.
Для иллюстрации этих свойств воспользуемся отношением с данными о поставщиках, приведенным на рис. 3.8 (см. стр. 119). Для удобства это отношение снова показано на рис. 6.1, но заголовок в нем расширен для включения имен типов.
210 Часть II. Реляционная модель Примечание. Формально мы должны были бы расширить также тело для включения имен атрибутов и типов. Например, запись S# для поставщика si должна была бы фактически выглядеть следующим образом.
S# S# S#('S1') Рис. 6.1. Отношение с данными о поставщиках, приведенное на рис. 3. Но для упрощения оставим тело этого отношения в таком же виде, в каком оно было первоначально представлено на рис. 3.8.
1. Отношения нормализованы Как было указано в разделе 6.2, каждый кортеж содержит точно одно значение для каждого из своих атрибутов, поэтому можно сделать неоспоримое заключение, что каждый кортеж в каждом отношении содержит точно одно значение для каждого из своих атрибутов. Отношение, которое соответствует этому свойству, называется нормализованным; иначе мысль можно выразить таким образом, что отношение находится в первой нормальной форме5, 1НФ.
Согласно этому определению, отношение, показанное на рис. 6.1, является нормализованным.
Примечание. Это первое свойство может показаться вполне очевидным и оно действительно является таковым, особенно в связи с тем, что (как мог уже заметить читатель) все отношения нормализованы по определению! Тем не менее, из этого свойства вытекают некоторые важные следствия. См. подраздел "Атрибуты со значениями в виде отношений" ниже в этом разделе, а также главу 19 (где речь идет о недостающей информации).
2. Атрибуты не характеризуются каким-либо упорядочением (например, слева направо) Как уже было сказано, компоненты кортежа не характеризуются каким-либо упорядочением (например, слева направо), и аналогичное утверждение является справедливым применительно к атрибутам отношения (фактически по той же причине, а именно, в связи с тем, что заголовок отношения представляет собой множество атрибутов, а множества в математике не характеризуются упорядочением своих элементов). Однако если мы изображаем отношение на бумаге в виде таблицы, то мы, естественно, вынуждены показывать столбцы этой таблицы в определенном порядке расположения слева направо, но читатель должен всегда учитывать, что этот порядок не имеет значения. Например, на рис. 6.1 столбцы отношения вполне могли быть показаны (допустим) в порядке слева направо, SNAME, CITY, STATUS, S#, и этот рисунок все равно представлял бы то же отношение, Эта форма получила название "первой" в связи с тем, что могут быть также определены некоторые "более высокие" нормальные формы — вторая, третья и т.д. (см. главы 12 и 13).
по меньшей мере, если оно рассматривается как объект реляционной модели6.
Поэтому не может быть такого понятия, как "первый атрибут" или "второй атрибут" (и т.д.), а также не может идти речь о "следующем атрибуте" (т.е. в отношении не определено понятие "следования"); атрибуты всегда должны быть указаны по именам, а не по их позициям. Благодаря этому устраняется значительная часть предпосылок для возникновения ошибок и появления крайне запутанных программ. Например, отсутствует возможность определять методы, не предусмотренные в системе и позволяющие каким-то образом "перебирать" один атрибут за другим, просто наращивая указатель. Эта ситуация отличается в лучшую сторону по сравнению со многими системами программирования, часто допускающими возможность вольно или невольно пользоваться тем, что логически не связанные элементы физически расположены близко друг от друга, несмотря на то, что это приводит к созданию программ, чреватых многочисленными ошибками.
3. Кортежи не характеризуются каким-либо упорядочением (например, сверху вниз) Это свойство следует из того факта, что тело отношения также представляет собой множество (кортежей); еще раз подчеркнем, что множества в математике не упорядочены. Но изображая отношения на бумаге в виде таблицы, мы вынуждены показывать строки этой таблицы в некотором порядке расположения сверху вниз;
тем не менее, читатель должен учитывать, что этот порядок не имеет значения.
Например, на рис. 6.1 строки вполне можно было бы также показать в обратном порядке, притом что сам рисунок по-прежнему представлял бы то же отношение.
Поэтому не существует такого понятия, как "первый кортеж", "пятый кортеж" или "97-й кортеж" отношения, кроме того, не существует такого понятия, как "следующий кортеж"; иными словами, в отношениях не определена позиционная адресация и нет понятия "следования". Заслуживает внимание то, что если бы указанные понятия были определены, потребовались бы также некоторые дополнительные операции, например, "выполнить выборку л-го кортежа", "вставить этот новый кортеж здесь", "переместить этот кортеж отсюда сюда" и т.д. А поскольку существует один и только один способ представления информации в реляционной модели (что является непосредственным следствием информационного принципа Кодда), очень мощным средством реляционной модели является то, что для обработки этой информации достаточно иметь одно и только одно множество операторов.
Рассмотрим последнее замечание более подробно. Фактически не вызывает сомнения такое утверждение, что если существует N разных способов представления информации, то требуется N различных множеств операторов, а если N > 1, то приходится реализовывать, документировать, объяснять студентам, учить самим, запоминать и использовать больше операторов. Но введение каждого дополнительного оператора приводит лишь к возрастанию сложности, а не выразительной мощи! Не существует каких-либо полезных операторов, которые могут применяться, только если N > 1,а не N= 1. Эта тема будет более подробно рассматриваться в главе 26 (см. [26.12]—[26.14] и [26.17]), а затем снова появится в главе 27.
По причинам, которые нас здесь не интересуют, отношения в математике, в отличие от их аналогов в реляционной модели, характеризуются упорядочением своих атрибутов слева направо (и это замечание, безусловно, относится и к кортежам).
212 Часть II. Реляционная модель Вернемся к описанию самих отношений. Безусловно, определенные требования по упорядочению кортежей сверху вниз (а также по упорядочению атрибутов слева направо) выдвигаются в связи с созданием интерфейса между базой данных и базовым языком, таким как С или COBOL (см. сведения о курсорах SQL и конструкции ORDER BY, приведенные в главе 4). Но эти требования налагает базовый язык, а не реляционная модель; в действительности базовый язык требует преобразования неупорядоченных отношений в упорядоченные списки, или массивы (кортежи), именно для того, чтобы приобрели смысл операции, подобные "выборке п-го кортежа". Аналогичным образом, определенные требования по упорядочению кортежей должны соблюдаться при представлении результатов запросов для конечного пользователя. Но эти требования не входят в состав реляционной модели как таковой; скорее, они составляют часть той среды, в которой определена сама реализация этой реляционной модели. 4. Отсутствие в отношении дубликатов кортежей Это свойство также следует из того факта, что тело отношения представляет собой множество; множества в математике не содержат дубликатов элементов (иначе эту мысль можно выразить таким образом, что все элементы множества являются различными).
Примечание. Это свойство также служит для иллюстрации идеи о том, что понятия отношения и таблицы являются разными, поскольку таблица может включать дубликаты строк (если не соблюдаются некоторые требования, позволяющие предотвратить такую возможность), а отношение, по определению, никогда не содержит каких-либо дубликатов кортежей.
И действительно, это является (или должно быть) очевидным, что само понятие "дубликатов кортежей" лишено смысла. Для упрощения примем предположение, что отношение, приведенное на рис. 6.1, имеет только два атрибута, s# и CITY (как показано в разделе 6.5, интерпретация этих атрибутов соответствует их назначению— "Поставщик s# находится в городе CITY"), а также предположим, что отношение содержит кортеж, согласно которому имеет место "истинный факт", что поставщик S1 находится в Лондоне. В таком случае, если бы отношение содержало дубликат указанного кортежа (при условии, что это вообще возможно), оно просто информировало бы нас о том же "истинном факте" во второй раз.
Но если нечто является истинным, то при многократном повторении оно не становится более истинным!
Развернутое описание проблем, которые могут быть вызваны наличием дубликатов кортежей в отношении, можно найти в [6.3] и [6.6].
Сравнение отношений и таблиц Для использования в дальнейшем представим в этом подразделе приведенный ниже список некоторых основных различий между формальным объектом, который является отношением как таковым, и неформальным объектом (таблицей), представляющим собой неформальное изображение этого формального объекта на бумаге.
1. Для каждого атрибута в заголовке отношения предусмотрено имя типа, но эти имена типов обычно не показаны на изображениях в виде таблицы.
2. Для каждого компонента каждого кортежа в теле отношения предусмотрено имя типа и имя атрибута, но эти имена типа и атрибута обычно не показаны на изо бражениях в виде таблицы.
3. Каждое значение атрибута в каждом кортеже в теле отношения является значени ем соответствующего типа, но эти значения на изображениях в виде таблицы обычно показаны в сокращенной форме, например, s1 вместо s# (' S1').
4. Столбцы в таблице характеризуются упорядочением слева направо, а атрибуты от Примечание. Важным следствием из этого различия является то, что столбцы могут иметь повторяющиеся имена или вообще не иметь имен. Например, рассмотрим следующий запрос SQL.
SELECT S.CITY, S.STATUS * 2, P.CITY FROM S, P ;
Какими будут имена столбцов в результатах этого запроса?
5. Строки таблицы характеризуются упорядочением сверху вниз, а кортежи отноше 6. Таблица может содержать дубликаты строк, а отношение не содержит дубликаты Приведенный список наиболее важных различий не является исчерпывающим. Ниже перечислены некоторые другие различия.
Безусловно, что таблицы обычно рассматриваются как имеющие по меньшей мере один столбец, а отношения не обязательно должны иметь хотя бы один атрибут (см. подраздел "Отношения без атрибутов" ниже в этом разделе).
Безусловно, допускается (по крайней мере, в языке SQL), чтобы таблицы включа ли неопределенные значения (NULL), в то время как для отношений это ни в коем случае не допускается (см. главу 19).
Безусловно, что таблицы являются "плоскими" (или двухмерными), а отноше ния — n-мерными (см. главу 22).
Из всего сказанного выше следует, что мы должны принять определенное соглашение о том, как "читать" подобные изображения в виде таблицы, чтобы иметь право рассматривать эти изображения как приемлемые средства представления отношений; иными словами, необходимо принять определенные правила интерпретации для таких изображений. Точнее, необходимо принять соглашение о том, что каждый столбец характеризуется соответствующим типом, каждое значение атрибута представляет собой значение определенного типа, упорядочение строк и столбцов не имеет значения и дубликаты строк не допускаются. Таблица может рассматриваться как приемлемое изображение отношения тогда и только тогда, когда соблюдаются все эти правила ее интерпретации.
Итак, теперь вполне очевидно, что в действительности между таблицей и отношением существуют значительные различия (но часто бывает удобно игнорировать эти различия). Отношение скорее следует считать таким, как сказано в его определении, — вполне абстрактным объектом, а таблица является конкретным изображением такого абстрактного объекта, обычно на бумаге. Следует еще раз подчеркнуть, что таблица и отношение 214 Часть II. Реляционная модель представляют собой разные объекты. Безусловно, между этими объектами есть много общего, поэтому обычно принято и вполне приемлемо рассматривать их как одинаковые, по меньшей мере, в неформальном изложении. Но если требуется полная ясность (и мы как раз хотим добиться полной ясности), то следует учитывать, что эти два понятия не являются полностью идентичными.
В заключение следует также отметить, что фактически одним из важных преимуществ реляционной модели является то, что ее основной абстрактный объект, отношение, имеет такое простое представление на бумаге. Именно благодаря этому простому представлению реляционные системы становятся удобными для использования и изучения, к тому же намного упрощается само обсуждение особенностей функционирования реляционных систем. Но, к сожалению, следует отметить, что этот простой способ представления может навести также на мысль, которая не соответствует действительности (например, о том, что отношение характеризуется упорядочением кортежей сверху вниз).
Атрибуты со значениями в виде отношения Как было отмечено в разделе 6.3, в общем случае в качестве основы для определения реляционных атрибутов может использоваться любой тип. Из этого, в частности, следует, что основой для определения атрибутов отношений могут явиться типы отношений, поскольку они, безусловно, представляют собой типы. Иными словами, атрибуты могут иметь значения в виде отношений, а это означает, что в отношениях могут применяться атрибуты, значениями которых, в свою очередь, являются отношения. Иначе говоря, допустимо существование таких отношений, в которые вложены другие отношения.
Пример такого отношения показан на рис. 6.2. Применительно к этому отношению можно отметить, что в данном отношении, во-первых, атрибут PQ имеет значение в виде отношения, во-вторых, его кардинальность и степень равны пяти, и в частности, втретьих, пустое множество деталей, поставляемых поставщиком S5, представлено в виде значения PQ, которое является пустым множеством (точнее, пустым отношением).
Рис. 6.2. Отношение с атрибутом, значением которого является отношение Основная причина, по которой мы здесь подчеркиваем возможность применения атрибутов со значениями в виде отношений, состоит в том, что в свое время такая возможность обычно считалась недопустимой. В действительности она рассматривалась как таковая и в предыдущих изданиях настоящей книги. Например, ниже приведена немного отредактированная выдержка из шестого издания.
Следует отметить, что все значения столбцов являются атомарными... Это означает, что в каждой позиции на пересечении строки и столбца (именно так!) в каждой таблице (именно так!) должно всегда находиться одно и только одно значение данных, а не группа из нескольких значений. Поэтому, например, в таблице ЕМР должны присутствовать такие строки вместо следующей одной строки.
Во втором варианте этой таблицы столбец ЕМР# представляет собой пример того, что обычно называют повторяющейся группой. Повторяющаяся группа — это столбец..., который содержит несколько значений в каждой строке (и, в общем, разное количество значений в различных строках). В реляционных базах данных повторяющиеся группы не допускаются; поэтому второй вариант приведенной выше таблицы не должен использоваться в реляционной системе.
И ниже в том же шестом издании мы находим следующее утверждение.
Домены (т.е. типы) содержат только атомарные значения... [Поэтому] отношения не должны включать повторяющиеся группы. Отношение, удовлетворяющее этому условию, называется нормализованным или (равным образом) находящимся в первой нормальной форме... В контексте реляционной модели термин отношение всегда принято трактовать как нормализованное отношение.
Но эти замечания были неправильными (по меньшей мере, не совсем правильными).
Они явились следствием того, что в свое время сам автор не понимал истинного характера типов (доменов). По причинам, которые будут обсуждаться в главе 12 (раздел 12.6), маловероятно, чтобы это заблуждение могло привести на практике к каким-либо очень серьезным ошибкам; тем не менее, автор считает свои долгом принести извинения всем, кого он ввел в заблуждение. По крайней мере, этот текст из шестого издания был правильным в тех местах, где в нем говорилось, что отношения в реляционной модели всегда нормализованы! Дополнительная информация по этой теме приведена также в главе 12.
216 Часть II Реляционная модель Отношения без атрибутов Каждое отношение имеет множество атрибутов, а поскольку пустое множество также, безусловно, представляет собой множество, то из этого следует, что возможно наличие такого отношения, которое имеет пустое множество атрибутов или, иными словами, вообще не имеет атрибутов. (Постарайтесь избежать путаницы: мы часто говорим о "пустых отношениях", подразумевая под этим отношения, телом которых является пустое множество кортежей, но здесь, напротив, речь идет об отношениях, заголовками которых служит пустое множество атрибутов.) Поэтому отношения без атрибутов являются, по меньшей мере, вполне допустимыми с математической точки зрения. Но что, возможно, покажется читателю наиболее удивительным, так это то, что эти отношения оказались чрезвычайно важными также и с практической точки зрения!
Для того чтобы перейти к более подробному изучению понятия отношения без атрибутов, вначале необходимо рассмотреть вопрос о том, может ли отношение без атрибутов содержать какие-либо кортежи. Ответ на этот вопрос (что также может показаться удивительным) является положительным. Точнее, подобное отношение может содержать, самое большее, один кортеж, а именно, нуль-арный кортеж (т.е. кортеж без компонентов), причем оно не может содержать больше одного такого кортежа, поскольку все нульарные кортежи являются дубликатами по отношению друг к другу. Таким образом, существуют два и только два отношения нулевой степени — содержащие лишь один кортеж и не содержащие вообще ни одного кортежа. Эти два отношения являются настолько важными, что, следуя Дарвену (Darwen) [6.5], автор предусмотрел для них псевдонимы. Первое отношение будет именоваться TABLE_DEE, а второе — TABLE_DUM или сокращенно DEE и DUM (DEE — это отношение с одним кортежем, aDUM — пустое).
Примечание. Для этих отношений нелегко изобразить таблицу! Принятый способ трактовки отношений как обычных таблиц начинает немного буксовать в случае отношений DEE И DUM.
Почему отношении DEE и DUM ЯВЛЯЮТСЯ такими важными? На этот вопрос есть несколько ответов, более или менее связанных между собой. Одним из этих ответов является то, что эти отношения в реляционной алгебре играют такую роль (см. главу 7), которая немного напоминает роль, принадлежащую пустому множеству в теории множеств или нулю в обычной арифметике. Другой ответ касается того, что вообще подразумевается под отношениями (см [6.5]); по сути DEE означает TRUE, или да, a DUM означает FALSE, или нет. Иными словами, эти отношения имеют наиболее фундаментальный смысл по сравнению со всеми другими отношениями. (Удобный способ запомнить, какое из этих отношений что означает, состоит в том, что в отношении DEE есть буквы "е", как и в слове yes — да.) В языке Tutorial D выражения TABLE_DEE и TABLE_DUM могут использоваться в качестве сокращений, соответственно, для следующих вызовов селектора отношений.
Пока мы не имеем возможности более подробно углубиться в эту тему; достаточно сказать, что в последующем изложении отношения DEE и DUM встретятся еще много раз.
Дополнительную информацию можно найти в [6.5].
Операции с отношениями В разделе 6.3 кратко рассматривались реляционные операции применения селектора, присваивания и сравнения на равенство. Вне всякого сомнения, операторы сравнения на неравенство "" не могут применяться к отношениям, но отношения, безусловно, могут стать предметом сравнений другого рода в дополнение к простому сравнению на равенство, как будет показано в этом разделе.
Реляционные операции сравнения Начнем с определения логического выражения нового типа, с оператором сравнения отношений, которое имеет следующий синтаксис.
Отношения, обозначенные двумя параметрами (реляционное выражение), должны принадлежать к одному и тому же типу, а оператором сравнения отношений должен быть один из следующих операторов.
=. Равно.
Подмножество.
Строгое подмножество.
Надмножество.
Строгое надмножество.
После этого можно разрешить использовать операцию в любом месте, где допускается применение логического выражения, например, в конструкции WHERE. Ниже приведен ряд примеров.
Это выражение имеет такой смысл: "Является ли проекция отношения поставщиков по атрибуту CITY равной проекции отношения деталей по атрибуту CITY?" Это выражение имеет такой смысл (представленный в нем вопрос немного перефразирован): "Есть ли такие поставщики, которые вообще не поставляют детали?" В частности, одной из операций реляционного сравнения, которая особенно часто применяется на практике, является операция проверки в целях определения того, равно ли указанное отношение пустому отношению того же типа (т.е. отношению, не содержащему кортежей). Для данного конкретного случая удобно иметь некоторый сокращенный способ проверки. Поэтому определим следующее выражение.
IS_EMPTY ( ) Это выражение возвращает истинное значение TRUE, если отношение, обозначенное как реляционное выражение является пустым, а в противном случае возвращает ложное значение FALSE.
218 Часть Н. Реляционная модель Другие операторы Еще одним широко распространенным требованием является обеспечение возможности проверить, присутствует ли указанный кортеж t в указанном отношении r.
Это выражение возвращает TRUE, если t присутствует в r, а в противном случае возвращает FALSE (" Є " является оператором проверки принадлежности к множеству; выражение t Є r можно читать как "t принадлежит к r", или "t является элементом r", или, проще всего, "t [имеется] в r").
Необходимо также иметь возможность извлечь один кортеж из отношения с кардинальностью один, следующим образом.
TUPLE FROM r Это выражение активизирует исключение, если r не содержит точно один кортеж; в противном случае оно возвращает лишь этот один кортеж.
Кроме операторов, описанных выше, предусмотрены также все универсальные операторы (соединение, сокращение, проекция и т.д.), которые определены в реляционной алгебре. Отложим подробное описание этих операторов до следующей главы.
Ссылка на тип отношения Точно так же, как схема именования типа кортежа, описанная в разделе 6.2, упрощает задачу определения типа результата выражения, в котором используется произвольный кортеж, так и схема именования типа отношения, описанная в разделе 6.3, упрощает задачу определения типа результата произвольного реляционного выражения. Более подробные сведения по этой теме приведены в главе 7, а в этом разделе остановимся на одном простом примере. Если дана переменная отношения поставщиков S, то выражение приводит к получению результата (отношения), который имеет следующий вид.
RELATION { S# S#, CITY CHAR } Аналогичные замечания относятся ко всем возможным реляционным выражениям.
Оператор ORDER BY Для удобного представления результатов весьма желательно поддерживать оператор ORDER BY, как и в языке SQL (см. главу 3). Подробное определение этого оператора здесь не приведено, поскольку его семантика, безусловно, должна быть очевидной.
Но следует обратить внимание на перечисленные ниже особенности этого оператора.
Оператор ORDER BY действует (по сути), сортируя кортежи в некоторой указанной последовательности, несмотря на то, что для кортежей не определены операторы "" (именно так!).
Оператор ORDER BY не является реляционным оператором, поскольку возвра щаемый им результат не представляет собой отношение.
Оператор ORDER BY не является также функцией, поскольку в общем с его помо щью может быть получено много разных наборов выходных данных для одного и того же входного набора.
В качестве примера следствия из последнего замечания рассмотрим результат применения операции ORDER BY CITY к отношению поставщиков, показанному на рис. 6.1.
Безусловно, эта операция способна возвратить любой из четырех различных результатов.
В отличие от этого, операторы реляционной алгебры несомненно являются функциями, поскольку они при получении любого заданного набора входных данных всегда возвращают только один соответствующий ему возможный набор выходных данных.
6.5. ПЕРЕМЕННЫЕ ОТНОШЕНИЯ Теперь обратимся к переменным отношения (relation variable, или сокращенно relvar).
Как было отмечено в главе 3, переменные отношения имеют две разновидности — базовые переменные отношения и представления (называемые также, соответственно, реальными и виртуальными переменными отношения). В данном разделе нас в основном интересует именно базовые переменные отношения (представления подробно рассматриваются в главе 10), но следует отметить, что все сказанное здесь применительно к переменным отношения без дополнительного уточнения распространяется на все переменные отношения в целом, включая представления.
Определение базовой переменной отношения Ниже показан синтаксис определения базовой переменной отношения.
VAR BASE
Параметр с обозначением типа отношения принимает следующую форму.RELATION { } Здесь параметр — разделенный запятыми список атрибутов. Это выражение фактически представляет собой вызов генератора типа RELATION, как описано в разделе 6.3). Параметр и необязательный параметр описаны в одном из следующих абзацев. Ниже в качестве примера приведены определения базовых переменных отношения для базы данных поставщиков и деталей (которые были также показаны на рис. 3.9).
VAR S BASE RELATION
SNAME NAME, STATUS
INTEGER, CITY CHAR
220 Часть II. Реляционная модель VAR P BASE RELATION { Р# Р#, PNAME NAME, COLOR COLOR,WEIGHT WEIGHT,
PRIMARY KEY { P#};
VAR SP BASE
PRIMARY KEY { S#, P# }REFERENCES S FOREIGN KEY { P#
} REFERENCES P ;
Пояснения 1. Эти три базовые переменные отношения имеют следующие типы (отношения).
RELATION { S# S#, SNAME NAME, STATUS INTEGER, CITY
CHAR } RELATION { P# P#, PNAME NAME, COLOR COLOR,WEIGHT WEIGHT, CITY
CHAR } RELATION { S# S#, P# P#, QTY QTY } 2. Все термины заголовок, тело, атрибут, кортеж, степень (и т.д.), которые были пе ред этим определены для значений отношения, интерпретируются также очевид ным образом применительно к переменным отношения.3. Все возможные значения любой отдельно взятой переменной отношения принадлежат к одному и тому же типу отношения, а именно к типу отношения, указанному в определении переменной отношения (указанному косвенно, если данная переменная отношения является представлением), и поэтому имеют одинаковый заголовок.
4. При определении базовой переменной отношения ей присваивается начальное зна чение, которое является пустым отношением соответствующего типа.
5. Определения потенциальных ключей подробно рассматриваются в главе 9, а на данный момент мы будем просто предполагать, что определение каждой базовой переменной отношения включает одно и только одно определение потенциаль ного ключа, в следующей конкретной форме.
PRIMARY KEY { } 6. Определения внешнего ключа также рассматриваются в главе 9.
7. Ввод определения новой переменной отношения вынуждает систему внести в свой каталог записи с описанием этой переменной отношения.
8. Как было отмечено в главе 3, переменные отношения, как и отношения, имеют соответствующий предикат. Таковым является предикат, общий для всех отноше ний, которые представляют собой возможные значения рассматриваемой пере менной отношения. Например, в случае переменной отношения поставщиков S предикат выглядит примерно следующим образом.
Поставщик с номером поставщика S# работает по контракту, имеет имя SNAME и статус STATUS, а также находится в городе CITY 9. Предполагается, что предусмотрены средства определения применяемых по умолчанию значений для атрибутов базовых переменных отношения. Применяемым по умолчанию значением заданного атрибута является такое значение, которое должно быть помещено в позицию соответствующего атрибута, если пользователь явно не предоставит нужное значение при вставке некоторого кортежа.
Подходящая синтаксическая конструкция языка Tutorial D для определения применяемых по умолчанию значений может принимать форму новой конструкции в определении базовой переменной отношения, скажем, DEFAULT { }, где каждая спецификация применяемого по умолчанию значения WEIGHT ) AS #_HEAVIER ) WHERE #_HEAVIER < 3 ) { ALL BUT Здесь имена WT и #_HEAVIER выбраны произвольным образом. Если взять за основу наши обычные данные, то результат будет состоять из деталей с номерами Р2, РЗ и Р6. В этой статье глубоко анализируются лимитирующие запросы, а также предлагается несколько сокращенных синтаксических форм как для записи этих запросов, так и для других целей.
Примечание. В [3.3] описан альтернативный подход к формулировке лимитирующих запросов, в котором предусмотрено использование нового реляционного оператора, RANK.
7.6. Goldstein R.C. and Strnad A.J. The MacAIMS Data Management System // Proc. ACM SICFIDET Workshop on Data Description and Access. — November 1970.
См. аннотацию к [7.7].
7.7. Strnad A.J. The Relational Approach to the Management of Data Bases // Proc. IFIP Congress. — Ljubljana, Yugoslavia. — August 1971.
Мы упоминаем систему MacAIMS [7.6], [7.7] в основном ради исторического интереса. Она является наиболее ранним примером системы, поддерживающей парные отношения и алгебраический язык. Интересным также является то, что эта система разрабатывалась параллельно с работой Кодда над реляционной моделью (и, до определенной степени, независимо). Однако, в отличие от работы Кодда, система MacAIMS не получила существенного развития.
7.8. Notley M.G. The Peterlee IS/1 System // IBM UK Scientific Centre Report UKSCMarch 1972.
См. аннотацию к [7.9].
7.9. Todd S.J.P. The Peterlee Relational Test Vehicle — A System Overview // IBM Sys. J. — Peterlee Relational Test Vehicle (PRTV) — это экспериментальная система, разработанная в научном центре компании IBM UK, в городе Питерли, Англия. Она была разработана на основе более ранней системы IS/1 [7.8], которая, вероятнее всего, явилась первой реализацией идей Кодда. В ней поддерживались n-арные отношения и версия алгебры под названием ISBL (Information System Base Language — базовый язык информационных систем). Эта версия реляционной алгебры основывалась на предложениях, изложенных в [7.10]. Первоисточником приведенных в этой главе идей, касающихся вывода типов отношений, являются алгебра ISBL и предложения из [7.10]. Система PRTV обладала следующими важными свойствами.
Поддерживала операторы RENAME, EXTEND и SUMMARIZE.
Включала в себя сложные средства для преобразования выражений (см. гла Включала средства отложенного вычисления, что важно как для оптимизации, так и для поддержки представлений (см. обсуждение конструкции WITH в дан Предусматривала возможность добавлять определенные пользователем опера 7.10. Hall P.A.V., Hitchcock P., and Todd S.J.P. An Algebra of Relations for Machine Computation // Conf. Record of the 2nd ACM Symposium on Principles of Programming Languages. — Palo Alto, Calif. — January 1975.
7.11. Klug A. Equivalence of Relational Algebra and Relational Calculus Query Languages Having Aggregate Functions // JACM 29. — July 1982. — № 3.
В статье определен ряд дополнений к реляционной алгебре и реляционному исчислению (см. главу 8), предназначенных для включения поддержки операций агрегирования, и демонстрируется эквивалентность полученных при этом двух расширенных формальных языков.
Реляционное исчисление 8.1 Введение 8.2. Исчисление кортежей 8.3. Примеры 8.4. Сравнительный анализ реляционного исчисления и реляционной алгебры 8.5. Вычислительные возможности 8.6. Средства языка SQL 8.7. Исчисление доменов 8.8. Язык запросов по образцу 8.9. Резюме 8.1. ВВЕДЕНИЕ Реляционная алгебра и реляционное исчисление представляют собой два альтернативных подхода. Принципиальное различие между ними состоит в следующем. Реляционная алгебра определяет в явном виде набор операций (соединение, объединение, проекция и т.д.), которые можно использовать, чтобы сообщить системе, как в базе данных из определенных отношений сформировать некоторое требуемое отношение, а реляционное исчисление просто задает систему обозначений для определения требуемого отношения в терминах существующих отношений. Например, рассмотрим запрос: "Выбрать номера поставщиков и названия городов, в которых находятся поставщики детали с номером Р2". Алгебраическая версия этого запроса может быть составлена примерно так (мы умышленно не используем формальный синтаксис, приведенный в главе7).
Выполнить соединение отношений поставщиков и поставок SР по атрибуту S#.
С помощью операции сокращения выделить из результатов этого тежи, которые относятся к детали с номером Р2.
290 Часть II. Реляционная модель Сформировать проекцию результатов этой операции сокращения по атрибутам s# Этот же запрос в терминах реляционного исчисления формулируется приблизительно следующим образом.
Получить атрибуты s# и CITY для таких поставщиков, для которых в отношении SP существует запись о поставке с тем же значением атрибута s# и со значением атрибута Р#, равным Р2.
В этой формулировке пользователь лишь указывает определенные характеристики требуемого результата, предоставляя системе решать, что именно и в какой последовательности соединять, проецировать и т.д., чтобы получить необходимый результат. Итак, можно сказать, что, по крайней мере, внешне формулировка запроса в терминах реляционного исчисления носит характер описания, а в терминах реляционной алгебры — предписания. В реляционном исчислении просто указывается, в чем заключается проблема, тогда как в реляционной алгебре задается процедура решения этой проблемы. Или, говоря очень неформально, алгебра имеет процедурный характер (пусть на высоком уровне, но все же процедурный, поскольку задает необходимые для выполнения процедуры), а исчисление — непроцедурный.
Подчеркнем, однако, что упомянутые различия существуют только внешне. На самом деле реляционная алгебра и реляционное исчисление логически эквивалентны. Каждому выражению в алгебре соответствует эквивалентное выражение в исчислении, и точно также каждому выражению в исчислении соответствует эквивалентное выражение в алгебре.
Это означает, что между ними существует взаимно-однозначное соответствие, а различия связаны лишь с разными стилями выражения: исчисление ближе к естественному языку, а алгебра — к языку программирования. Но, повторим еще раз, эти различия только кажущиеся, а не реальные. В частности, ни один из этих подходов нельзя назвать "более непроцедурным" по сравнению с другим. Подробнее вопрос эквивалентности этих двух подходов будет рассматриваться в разделе 8.4 настоящей главы.
Реляционное исчисление основано на разделе математической логики, который называется исчислением предикатов. Идея использования исчисления предикатов в качестве основы языка баз данных впервые была высказана в статье Кунса (Kuhns) [8.6]. Понятие реляционного исчисления, т.е. специального метода применения исчисления предикатов в реляционных базах данных, впервые было сформулировано Коддом в [6.1], а в [8.1] Кода представил язык, основанный непосредственно на реляционном исчислении и названный "подъязыком данных ALPHA". Сам язык ALPHA никогда не был реализован, однако язык QUEL [8.5], [8.10]—[8.12], который действительно был реализован и некоторое время серьезно конкурировал с языком SQL, очень походил на язык ALPHA, оказавший заметное влияние на построение языка QUEL.
Основным средством реляционного исчисления является понятие переменной области значений. Согласно краткому определению, переменная области значений — это переменная, принимающая значения из некоторого заданного отношения, т.е. переменная, допустимыми значениями которой являются кортежи заданного отношения. Другими словами, если переменная области значений v изменяется в пределах отношения г, то в любой конкретный момент выражение "v" представляет некоторый кортеж t отношения г.
Например, запрос "Получить номера поставщиков, находящихся в Лондоне" может быть представлен на языке QUEL следующим образом.
RANGE OF SX IS S ;
RETRIEVE ( SX.S# ) WHERE SX.CITY = "London" ;Единственной переменной области значений здесь является переменная SX, которая принимает значения из отношения, представляющего собой текущее значение переменной отношения S (оператор RANGE — оператор определения этой переменной области значений). Оператор RETRIEVE означает следующее: "Для каждого возможного значения переменной SX выбирать компонент S# этого значения тогда и только тогда, когда компонентом CITY этого значения является London".
В связи с тем, что первоначальная версия реляционного исчисления основана на переменных области значений (в отличие от исчисления доменов, речь о котором пойдет ниже), ее называют также исчислением кортежей. Исчисление кортежей подробно описано в разделе 8.2.
Примечание. Для удобства примем следующее соглашение: далее в этой книге термины исчисление и реляционное исчисление, приведенные без такого уточнения, как кортежей или доменов, будут означать именно исчисление кортежей (там, где это играет какую-то роль).