Скачиваний:
102
Добавлен:
02.05.2014
Размер:
2.3 Mб
Скачать

7.7.16. Определить номера деталей, которые либо весят более 16 фунтов, либо поставляются поставщиком с номером 's2', либо и то, и другое

SELECT P.Pt

FROM Р

WHERE P.WEIGHT > 16.0 UNION

SELECT SP.Pt

FROM SP

WHERE SP.St = 'S2' ;

Лишние повторяющиеся строки всегда исключаются из результата выполнения не-уточненных операторов ONION, INTERSECT и EXCEPT (в языке SQL оператор EXCEPT слу­жит аналогом операции MINUS реляционной алгебры). Однако язык SQL также поддер­живает уточненные варианты этих операторов (UNION ALL, INTERSECT ALL и EXCEPT ALL), при которых повторяющиеся строки (если они есть) сохраняются. Приме­ры с этими вариантами операторов умышленно опускаются.

В заключение отметим, что, хотя список примеров операций выборки был доста­точно большим, о многих возможностях языка SQL здесь даже не упоминалось. Язык SQL в действительности является чрезвычайно избыточным [4.18] в том смыс­ле, что почти всегда существует множество способов формулирования одного и того же запроса и нам не хватит места, чтобы описать все возможные формулировки и все возможные опции даже для сравнительно небольшого числа примеров, которые приводились в этой главе.

7.8. Резюме

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

Реляционное исчисление существует в двух версиях: исчисление кортежей и исчис­ление доменов. Основное различие между ними состоит в том, что переменные исчис­ления кортежей изменяются на отношениях, а переменные исчисления доменов изме­няются на доменах.

Выражение исчисления кортежей состоит из прототипа кортежа и необязательного предложения WHERE, содержащего логическое выражение или формулу WFF ("правильно построенную формулу"). Подобная формула WFF может включать кванторы (EXISTS и F0RALL), свободные и связанные ссылки на переменные, логические (булевы) операторы (AND, OR, NOT и др.) и т.д. Каждая свободная переменная, которая встречается в формуле WFF, также должна быть упомянута в прототипе кортежа.

Замечание. В настоящей главе явно этот вопрос не затрагивался, но выражения реля­ционного исчисления предназначены, по существу, для тех же целей, что и выражения реляционной алгебры (см. раздел 6.6 главы 6).

На примере было показано, как алгоритм редукции Кодда может использоваться для преобразования произвольного выражения реляционного исчисления в эквивалент­ное выражение реляционной алгебры, таким образом подготавливая почву для выбора возможной стратегии реализации исчисления. Вновь обратившись к вопросу реляцион­ной полноты, мы кратко обсудили, каким образом можно доказать, что некоторый язык L является полным в этом смысле.

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

И наконец, вашему вниманию был представлен обзор соответствующих средств язы­ка SQL. Язык SQL является своеобразной смесью реляционной алгебры и исчисления (кортежей). Например, в нем есть прямая поддержка таких операций реляционной алгеб­ры, как соединение и объединение, но одновременно с этим используются переменные кортежей и квантор существования из реляционного исчисления. SQL-запрос представ­ляет собой табличное выражение. Обычно такая конструкция содержит единственное выражение выборки, однако поддерживаются и различные типы явных выражений операций соединения (JOIN), причем выражения соединения и выборки могут комбини­роваться произвольным образом с помощью операторов ONION, INTERSECT и EXCEPT. Также упоминалось о возможности использования предложения ORDER BY для определе­ния упорядоченности строк в таблице, являющейся результатом вычисления данного табличного выражения (любого вида).

В частности, были описаны следующие компоненты выражений выборки.

  • Базовое предложение SELECT, в том числе использование ключевого слова DISTINCT, скалярных выражений, введение имен результирующих столбцов и ис­пользование предложения SELECT *

  • Предложение FROM, включая использование переменных кортежей

  • Предложение WHERE, включая использование оператора EXISTS

  • Предложения GROUP BY и HAVING, включая использование обобщающих функ­ций COUNT, SUM, AVG, МАХ и MIN

  • Использование подзапросов в предложениях SELECT, FROM и WHERE

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

Упражнения

7.1. Пусть р(х) и q — произвольные формулы WFF, в которых переменная х соответствен- но используется и не используется в качестве свободной переменной. Какие из сле- дующих формулировок верны? (Здесь символ "=>" означает "следует", а символ "=" оз- начает "эквивалентно". Обратите внимание, что если А => В и В => А, то А н В.)

а) EXISTS х ( q ) s q

б) FORALL х ( q ) = q

в) EXISTS x ( p (x) AND q ) = EXISTS x ( p (x) ) AND q r) FORALL x ( p (x) AND q ) = FORALL x ( p (x) ) AND q д) FORALL x ( p (x) ) => EXISTS x ( p (x) )

7.2. Пусть p(x,y) — это произвольная формула WFF со свободными переменными х и у. Какие из следующих формулировок верны?

а) EXISTS х EXISTS у ( р(х,у) ) = EXISTS у EXISTS х ( р(х,у) )

б) FORALL х FORALL у ( р(х,у) ) н FORALL у FORALL х ( р(х,у) )

в) FORALL х ( р(х,у) ) = NOT EXISTS х ( NOT р(х,у) )

г) EXISTS х ( р(х,у) ) з NOT FORALL X ( NOT р(х,у) )

д) EXISTS х FORALL у ( p(x,y) ) = FORALL у EXISTS x ( p(x,y) )

е) EXISTS у FORALL x ( p(x,y) ) => FORALL x EXISTS у ( p(x,y) )

7.3. Пусть pjx) и q(y) — произвольные формулы WFF со свободными переменными х и у соответственно. Какие из следующих формулировок верны?

а) EXISTS х ( р(х) ) AND EXISTS у ( q(y) ) = EXISTS х EXISTS у ( p(x) AND q(y) )

б) EXISTS x j IF p(x) THEN q(x) END IF ) s

IF FORALL x ( p(x) ) THEN EXISTS x ( q(x) ) END IF

7.4. Еще раз обратимся к запросу из примера 7.3.8: "Определить номера поставщи- ков по крайней мере всех типов деталей, поставляемых поставщиком с номером 'S2'". Для этого запроса возможна следующая формулировка в терминах исчис- ления кортежей.

SX.St WHERE FORALL SPY ( IF SPY.St = 'S2' THEN

EXISTS SPZ ( SPZ.SI = SX.St AND SPZ.Pt = SPY.Pt )

END IF )

(Здесь SPZ — это еще одна переменная кортежа, изменяющаяся на отношении по­ставок.) Что будет возвращено при выполнении этого запроса, если поставщик с номером 'S2' в данный момент не поставляет никаких деталей? Что будет, если в приведенном выражении переменную SX всюду заменить переменной SPX?

7.5. Вот пример запроса к базе данных поставщиков, деталей и проектов (используются обычные упрощения для имен переменных).

( PX.NAME, PX.CITY ) WHERE FORALL SX FORALL JX EXISTS SPJX

( SX.CITY = 'London' AND JX.CITY = 'Paris' AND SPJX.St = SX.St AND SPJX.Pt = PX.Pt AND SPJX.Jt = JX.Jt AND SPJX.QTY < QTY ( 500 ) )

а) Сформулируйте этот запрос в словесной форме.

б) Возьмите на себя роль СУБД и выполните этот запрос по предложенному Код- дом алгоритму редукции. Можете ли вы указать какие-либо улучшения, кото- рые целесообразно внести в данный алгоритм?

  1. Выразите в терминах исчисления кортежей запрос "Получить три самые тяжелые детали".

  2. Рассмотрим отношение спецификации материалов переменной-отношения PART_STRUCTURE, представленной в главе 4. (Соответствующие SQL-определения даны в ответе к упр. 4.6, а пример значения приведен на рис. 4.6.) Обратимся к широкоизвестному запросу разузлования деталей "Получить номера деталей, ко­торые на любых уровнях вхождения являются компонентами некоторой заданной детали (скажем, детали с номером 'Р1')". Результат этого запроса, например от­

ношение PART_LIST (которое, безусловно, является отношением, производным от исходного отношения PART_STRUCTURE), нельзя сформулировать в виде единствен­ного выражения начального реляционного исчисления (или реляционной алгебры). Иначе говоря, производное отношение PART_LIST не может быть получено с по­мощью единственного выражения начального реляционного исчисления (или ре­ляционной алгебры). Почему?

  1. Предположим, что переменную-отношение поставщиков S заменили набором пе­ременных-отношений LS, PS, AS... по одной переменной-отношению для каждого города (например, переменная-отношение LS будет содержать кортежи только для поставщиков из Лондона). Предположим также, что неизвестно, какие именно су­ществуют города, в которых находятся поставщики, и поэтому неизвестно, сколько имеется таких переменных-отношений. Рассмотрим запрос "Существует ли в базе данных поставщик с номером 'S1'?". Можно ли такой запрос выразить в терминах исчисления (или алгебры)? Обоснуйте свой ответ.

  2. Покажите, что язык SQL является реляционно полным.

  3. Существуют ли в языке SQL эквиваленты реляционных операторов EXTEND и SUMMARIZE?

  4. Существуют ли в языке SQL эквиваленты операторов реляционных сравнений?

  5. Приведите как можно больше различных формулировок на языке SQL для запроса "Выбрать имена поставщиков детали с номером 'Р2"\

Упражнения по запросам

В основу всех остальных упражнений была положена база данных поставщиков, деталей и проектов (см. рис. 4.5 в главе 4 и ответ к упр. 5.4 в главе 5). В каждом случае вам будет предложено записать выражение, позволяющее выполнить ука­занный запрос. (В качестве интересной вариации попытайтесь сформулировать по­становку той или иной задачи, глядя на ее ответ.)

  1. Дайте ответы к упр. 6.13—6.50 в терминах исчисления кортежей.

  2. Дайте ответы к упр. 6.13-6.50 в терминах исчисления доменов.

  3. Дайте ответы к упр. 6.13-6.50, используя средства языка SQL.

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

В дополнение к приведенному ниже списку обратитесь также к [4.7], где описыва­ется несколько расширений языка SQL, предназначенных для работы с транзитив­ным замыканием и другими подобными операциями. Эти расширения очень напо­минают соответствующие возможности, предусмотренные стандартом SQL3, ко­торые кратко описываются в приложении Б. По вопросу внедрения подобных средств в реляционное исчисление обратитесь к главе 23.

7.1. Codd E.F. A Data Base Sublanguage Founded on the Relational Calculus // Proc. 1971 ACM SIGFIDET Workshop on Data Description, Access and Control. — San Diego, Calif. —November, 1971.

  1. Date C.J. A Note on the Relation Calculus // ACM SIGMOD Record 18. — 1989. — № 4. Переиздано: An Anomaly in Codd's Reduction Algorithm // Relational Database Writings 1989-1991. Reading, Mass.: Addison-Wesley, 1992.

  2. Date C.J. Why Quantifier Order Is Important // C.J. Date and Hugh Darwen. Relational Database Writings 1989-1991. — Reading, Mass.: Addison-Wesley, 1992.

  3. Date C.J. Relational Calculus as an Aid to Effective Query Formulation // C.J. Date and Hugh Darwen. Relational Database Writings 1989-1991.— Reading, Mass.: Addison-Wesley, 1992.

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

7.5. Held G.D., Stonebraker M.R., and Wong E. INGRES — A Relational Data Base System // Proc. NCC 44. — Anaheim, Calif. Montvale, N.J.: AFIPS Press, May, 1975.

С середины и до конца 70-х годов разрабатывались два главных реляционных про­тотипа: система System R в фирме IBM и система INGRES в Калифорнийском уни­верситете в Беркли. Оба эти проекта имели очень большое значение в исследова­тельском мире и впоследствии лидировали среди коммерческих систем как СУБД DB2 (в случае системы System R) и как коммерческий продукт INGRES (в случае системы INGRES).

Замечание. Прототип INGRES иногда называют "университетским INGRES" [7.11], чтобы отличать его от коммерческой версии этой системы. Учебный обзор коммерческой версии можно найти в [1.5].

Система INGRES вначале не являлась SQL-системой, поскольку исходно поддер­живала язык QUEL (Query Language), который во многих отношениях технически превосходил SQL. В самом деле, язык QUEL по-прежнему составляет основу дос­таточного числа современных исследований баз данных, а примеры на языке QUEL до сих пор появляются в исследовательской литературе. Данная статья, в которой впервые был описан прототип INGRES, включает предварительное опре­деление языка QUEL. См. также [7.10]-[7.12].

  1. Kuhns J.L. Answering Questions by Computer: A Logical Study // Report RM-5428-PR, Rand Corp. — Santa Monica, Calif., 1967.

  2. Lacrorix M., Pirotte A. Domain-Oriented Relational Languages // Proc. 3rd Int. Conf. on Very Large Data Bases. — Tokyo, Japan., October, 1977.

  3. Merrett Т.Н. The Extended Relational Algebra, A Basis for Query Languages // Shneiderman B. (ed.). Databases: Improving Usability and Responsiveness. New York, N.Y.: Academic Press., 1978.

Назначением этой статьи является введение кванторов в алгебру — не просто кван­торов существования и кванторов всеобщности реляционного исчисления, а более общих кванторов "количество" и "соотношение". С их помощью можно выразить та­кие условия, как "по крайней мере три", "не более половины", "нечетное число" и т.д.

7.9. Negri М., Pelagatti G., Sbattella L. Formal Semantics of SQL Queries // ACM TODS. — September, 1991.— 16, № 3.

Цитата из резюме: "Семантика SQL-запросов формально определена с помо­щью набора правил, определяющих преобразование на основе синтаксиса SQL-запроса в формальную модель, называемую расширенным исчислением трехзначных предикатов (Extended Three Valued Predicate Calculus— E3VPC), которая большей частью основана на хорошо известных математических поня­тиях. Приведены также правила преобразования общего выражения E3VPC в каноническую форму; [дополнительно] полностью решены проблемы, подоб­ные анализу эквивалентности SQL-запросов". Однако отметим, что рассматри­ваемый здесь диалект языка SQL— это только первая версия стандарта (SQL/86), а не стандарт SQL/92.

7.10. Stonebraker М. The INGRES Papers: The Anatomy of a Relational Database Management System // Reading, Mass.: Addison-Wesley, 1986.

Собрание некоторых наиболее важных документов университетского проекта INGRES под редакцией одного из первых создателей этого проекта. (В собрание включены статьи [7.11], [7.12].) Насколько известно автору настоящей книги, это единственное доступное издание, в котором подробно описываются проект и реа­лизация полномасштабной реляционной СУБД. Весьма ценный материал для серь­езных студентов.

7.11. Stonebraker М., Wong Е., Kreps P., Held G. The Design Implementation of INGRES // ACM TODS. — September, 1976. — 1, № 3. (Переиздано [7.10].)

Подробное описание университетского прототипа INGRES.

7.12. Stonebraker М. Retrospection on a Data Base System // ACM TODS. — 1980. — 5, № 2. (Переиздано [7.10].)

Доклад по истории проекта прототипа INGRES (до января 1979 года). Акцент сде­лан скорее на ошибках и полученных уроках, чем на успехах.

7.13. Ullman J. D. Principles of Database and Knowledge-Base Systems: Volume I. Rockville, Md.: Computer Science Press, 1988.

Книга Ульмана, в отличие от данной книги, содержит более формальное изложе­ние реляционного исчисления и связанных с ним вопросов. В частности, в ней обсуждается понятие безопасности выражений исчисления. Это имеет значение при адаптации немного измененной версии исчисления, в которой переменные кортежей не определяются отдельными операторами RANGE, а связываются с об­ластью значений посредством явных условий в предложении WHERE. В такой вер­сии исчисления запрос "Получить имена всех поставщиков из Лондона", напри­мер, может выглядеть так.

SX WHERE SX е S AND SX.CITY = 'London'

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

SX WHERE NOT ( SX е S )

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

этом смысле, В книге Ульмана описаны такие правила (для исчисления как корте­жей, так и доменов). Следует отметить, что в оригинальном исчислении Кодда та­кие правила были.

7.14. Zloof М. М. Query By Example // Proc. NCC 44.— Anaheim, Calif., 1975.— Montvale, N.J.: AF1PS Press, 1977.

Описанный в этой работе реляционный язык Query-By-Example (QBE) включает элементы исчисления кортежей и в еще большей степени — элементы исчисле­ния доменов. Привлекательный и интуитивно понятный синтаксис языка осно­вывается на идее формирования элементов в "шаблонные таблицы" на экране дисплея вместо записи линейных операторов. Например, формулировка языка QBE для запроса "Получить имена поставщиков по крайней мере одной детали, поставляемой поставщиком с номером 'S2'" (довольно сложный запрос) может выглядеть следующим образом.

S

Si

SNAME

SP

Si

р#

SP

Si

Pi

SX

P. NX

SX

PX

S2

PX

Пояснение. Пользователь обращается к системе с запросом отобразить на экране три шаблонные таблицы (одну — для отношения S и две — для отношения SP), по­сле чего формирует в них элементы, как показано выше. Элементы, начинающиеся символом подчеркивания, представляют "образцы" (т.е. переменные доменов); ос­тальные элементы представляют собой литералы. В этом случае пользователь об­ращается к системе с запросом "предоставить" ("Р") значения имен поставщиков ( NX), таких, что если это поставщик _SX, то _SX поставляет некоторую деталь _РХ, а деталь _РХ, в свою очередь, также поставляется поставщиком с номером 'S2'. Заметьте, что под кванторами существования подразумевается (как, кстати, и под кванторами существования в языке QUEL) совсем другой смысл, поэтому данный синтаксис прост для понимания.

Вот другой пример: "Определить все пары номеров поставщиков, которые нахо­дятся в одном городе".

S

si

CITY

SX

CZ

P.

_SX

_SY

~SY

~CZ

К сожалению, язык QBE не является реляционно полным, а конкретнее — не под­держивает (в полной мере) негативный квантор существования (NOT EXISTS). Вследствие этого определенные запросы (например, "Получить имена поставщи­ков всех типов деталей") не могут быть выражены в языке QBE. (На самом деле язык QBE вначале "поддерживал" квантор NOT EXISTS, по крайней мере неявно, но построение всегда было сопряжено с некоторыми трудностями. Основная проблема заключалась в том, что не было способа указать порядок, в ко­тором различные неявные кванторы могли бы быть применены, а этот порядок, к сожалению, очень важен; см. [7.3] или ответ к упр. 7.2. Поэтому определенные за­просы получались неоднозначными [7.3].)

Злуф (автор этой работы) первым изобрел и разработал язык QBE. Данная статья была первой из многих статей, написанных Злуфом по этой тематике.

Ответы к некоторым упражнениям

7.1. а) верно; 6) верно; в) верно; г) верно; д) не верно.

Замечание. Причина, по которой утверждение д не верно, состоит в том, что при­менение квантора FORALL к пустому множеству всегда дает значение истина. И на­оборот, применение квантора EXISTS к пустому множеству всегда дает значение ложь. Поэтому, например, если утверждение "Все фиолетовые детали весят более 100 фунтов" истинно, то это необязательно означает, что действительно существу­ют фиолетовые детали.

Заметим, что тождества (верные!) могут использоваться в качестве основы для множества правил преобразования выражений исчисления аналогично алгебраиче­ским правилам преобразования, упоминавшимся в главе 6 и подробно обсуждаю­щимися в главе 17. Аналогичные замечания также применимы к упр. 7.2 и 7.3.

7.2. а) верно; б) верно; в) верно (этот пример рассматривался в основном тексте главы); г) верно (следовательно, один квантор может быть определен через другой); д) не верно; е) верно. Обратите внимание, что последовательность одинаковых кванторов — как в тождествах а и б — может быть записана в лю- бом порядке без изменения смысла выражения, тогда как для разных кванто- ров — как показано в тождестве д — такой порядок имеет существенное зна- чение. Чтобы проиллюстрировать последнее, предположим, что переменные х и у изменяются на множестве целых чисел и р является формулой WFF у > х. Очевидно,что формула

FORALL х EXISTS у ( у > х )

("для всех целых х существует целое у, большее х") дает значение истина, тогда как формула

EXISTS у FORALL X (у > X )

("существует целое у, большее любого целого х") дает значение ложь. Таким обра­зом, перестановка неодинаковых кванторов изменяет значение выражения. Поэто­му в языке запросов, основанном на реляционном исчислении, перестановка не­одинаковых кванторов в предложении WHERE изменяет значение запроса [7.3].

  1. а) верно; б) верно.

  2. Если поставщик с номером 'S2' в данный момент не поставляет никаких дета­лей, исходный запрос будет возвращать все номера поставщиков из отношения S (включая, в частности, самого поставщика с номером 'S2', сведения о котором согласно нашему предположению содержатся в отношении S, но отсутствуют в SP). Если везде заменить переменную SX переменной SPX, то запрос будет воз­вращать все номера поставщиков, содержащихся в отношении SP. Различие ме­жду двумя формулировками следующее: первая означает "Получить номера по­ставщиков всех типов деталей, поставляемых поставщиком с номером 'S2'" (что и требуется), а вторая — "Получить номера поставщиков по крайней мере одной детали и по крайней мере всех типов деталей, которые поставляются поставщи­ком с номером 'S2'".

  1. а) Получить наименование детали и название города для деталей, поставляемых для каждого проекта в Париже каждым поставщиком в Лондоне в количестве ме­нее 500 штук, б) Результат выполнения этого запроса — пустое множество.

  2. Это упражнение очень трудное! Особенно если мы будем учитывать, что вес деталей неуникален. (Если бы их вес был уникален, можно было бы перефор­мулировать запрос так: "Получить все детали, такие, что количество более тя­желых деталей меньше трех".) Упражнение настолько трудное, что мы даже не пытаемся дать здесь полное решение на языке реляционного исчисления. Оно очень хорошо иллюстрирует тот факт, что реляционная полнота является лишь основным критерием выразительной силы языка, но необязательно достаточ­ным. (Следующие два примера также иллюстрируют этот момент.) Подобные запросы обсуждаются в [6.4].

  3. Пусть PSA, PSB, PSC, PSn— переменные кортежей, изменяющиеся на перемен­ной-отношении PART_STRUCTURE. Предположим также, что заданная деталь — это деталь с номером 'Р1'. Тогда имеем следующее.

а) Выражение реляционного исчисления для запроса "Получить номера деталей для всех типов деталей, которые являются компонентами детали с номером 'р1' на первом уровне входимости" будет таким.

PSA.MIN0R_Pi WHERE PSA.MAJOR_Pt = Р ( 'PI' )

б) Выражение реляционного исчисления для запроса "Получить номера деталей для всех деталей, которые являются компонентами детали с номером 'р1' на втором уровне входимости" будет таким.

PSB.MINOR Pt WHERE EXISTS PSA

( PSA.MAJOR PI = P ( 'PI' ) AND PSB.MAJOR~P| = PSA.MINOR_P| )

в) Выражение реляционного исчисления для запроса "Получить номера деталей для всех деталей, которые являются компонентами детали с номером 'р1' на третьем уровне входимости" будет таким.

PSC.MINOR_Pt WHERE EXISTS PSA EXISTS PSB

( PSA.MAJOR_P| = P ( 'PI' ) AND PSB.MAJOR_Pl = PSA.MINOR_Pl AND PSC.MAJOR_Pi = PSB.MINOR_Pl )

И т.д. Выражение реляционного исчисления для запроса "Получить номера де­талей для всех деталей, которые являются компонентами детали с номером 'р1' на и-м уровне входимости" будет таким.

PSn.MINOR_Pf WHERE EXISTS PSA EXISTS PSB ... EXISTS PS(fl-l) ( PSA.MAJOR_Pi = P ( 'PI' ) AND PSB.MAJOR_Pf = PSA.MINOR_Pf AND PSC.MAJOR~Pf = PSB.MINOR~Pt AND

7.. AND

PSn.MAJOR_Pf = PS(fl-l).MINOR_Pt )

Для построения отношения PMT_LIST все результирующие отношения из пп. а, б,в,...,п необходимо объединить.

Проблема заключается в том, что невозможно записать п таких выражений, если значение п неизвестно. Следовательно, запрос разузлования детали является клас­сической иллюстрацией задачи, которая не может быть сформулирована с помо­щью отдельных выражений на языке, обладающем лишь свойством реляционной полноты, т.е. на языке, который не является более мощным, чем реляционное ис­числение (или алгебра). Частично эту проблему можно решить с помощью опера­тора TCL0SE, кратко рассмотренного в главе 6 (но только частично). Дальнейшие подробности выходят за рамки этой книги.

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

7.8. Этот запрос нельзя выразить ни в терминах исчисления, ни в терминах алгебры. Например, чтобы выразить его в терминах исчисления, по существу, потребова- лось бы уметь выражать нечто подобное следующему.

"Существует ли отношение г, такое, что в этом отношении г имеется кортеж t, та­кой, что t.SI = Si ( 'SI' )?"

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

Кстати, обратите внимание, что рассматриваемый запрос — это запрос типа "Да — нет" (причем, желаемый ответ — чаще всего значение истина). Поэто­му читателю может показаться, что запрос нельзя выразить в терминах исчис­ления или с помощью алгебры, потому что выражения реляционного исчисле­ния и алгебры принимают значения отношений, а не логические. Однако за­просы типа "Да — нет" могут быть выражены в терминах исчисления и алгеб­ры, если они правильно реализованы! Главная трудность заключается в том, чтобы понять, что результаты "да" и "нет" (эквивалентные значениям истина и ложь) могут быть представлены как отношения. Рассматриваемые отно­шения — это TABLE_DEE и TABLE DUM соответственно. Более подробное обсуж­дение этих отношений приводится в [5.5].

7.9. Для подтверждения реляционной полноты языка SQL необходимо сначала пока- зать, что существуют SQL-выражения для каждой из пяти примитивных операций реляционной алгебры (выборки, проекции, произведения, объединения и вычита- ния), а затем доказать, что операнды таких SQL-выражений могут, в свою очередь, быть произвольными выражениями языка SQL.

Начнем с предварительного замечания о том, что язык SQL фактически поддержи­вает оператор переименования реляционной алгебры RENAME после введения в стандарт SQL/92 необязательной спецификации AS <иш столбца> в предложении SELECT. Следовательно, можно быть уверенным, что все имена столбцов в табли­цах правильны и, в частности, что операнды операций произведения, объединения и вычитания удовлетворяют требованиям реляционной алгебры (в нашей версии) в отношении именования столбцов. Более того, указанные требования к именованию столбцов операндов действительно удовлетворяются: правила вывода имен столб­цов в языке SQL фактически совпадают с аналогичными правилами реляционной алгебры (в нашей версии), что было показано в главе 6.

Вот выражения языка SQL, соответствующие пяти примитивным операциям алгебры. Алгебра Язык SQL

A WHERE р

А {X, у,..., Z}

A TIMES В A UNION В A MINUS В

SELECT * FROM A WHERE р

SELECT DISTINCT X, y,...,Z FROM A

A CROSS JOIN В

SELECT * FROM A UNION SELECT * FROM В SELECT * FROM A EXCEPT SELECT * FROM В

Обратившись к грамматике табличных выражений языка SQL, которая описывается в приложении А, можно увидеть, что переменные А и В в приведенных выше SQL-выражениях по сути являются значениями параметра <ссылка на таблицу>. Можно убедиться еще и в том, что если заключить каждое из пяти показанных SQL-выражений в скобки, то оно также станет допустимым значением этого же парамет­ра7. Отсюда следует, что язык SQL на самом деле является реляционно полным.

Замечание. В действительности во всем вышесказанном есть один недостаток: язык SQL не поддерживает проекций по нулевому количеству столбцов (поскольку он не поддерживает пустых предложений SELECT). Как следствие язык SQL не под­держивает таблиц TABLE_DEE и TABLE_DUM [5.5].

7.10. Язык SQL поддерживает операцию EXTEND, но не SUMMARIZE (по крайней мере, не не­посредственно). Что касается операции EXTEND, то выражение реляционной алгебры

EXTEND A ADD ехр AS Z

в языке SQL может быть представлено так.

SELECT A.*, exp' AS Z FROM ( А ) AS А

7 Здесь мы игнорируем mom факт, что в языке SQL параметр <ССЫЛКа на таблицу> в дей­ствительности требует включения в свое значение определения переменной кортежа с пустой областью значений (см. приложение А).


Выражение ехр' в предложении SELECT является SQL-аналогом операнда ехр в выражении EXTEND. Заключенная в скобки ссылка на переменную А представляет собой значение параметра <ссылка на та6пицу> произвольной сложности

(соответствующую операнду А оператора EXTEND). Вторая ссылка А в предложе­нии FROM — имя переменной кортежа.

Что касается операции SUMMARIZE, основная проблема состоит в том, что выраже­ние реляционной алгебры

SUMMARIZE A PER В ...

возвращает результат, кардинальность которого равна кардинальности операнда В, в то время как "эквивалентное" этой функции SQL-выражение

SELECT ... FROM А GROUP BY С ;

возвращает результат с кардинальностью, равной кардинальности проекции табли­цы А по атрибуту С.

7.11. Язык SQL не поддерживает реляционных сравнений непосредственно. Однако по- добные операции можно смоделировать, хотя и в виде очень громоздких выраже- ний. Например, реляционное сравнение А = В (где А и В — отношения) можно ус- пешно смоделировать с помощью следующего SQL-выражения.

NOT EXISTS ( SELECT * FROM A

WHERE NOT EXISTS ( SELECT * FROM В

WHERE к-строка = В-строка ) )

Здесь операнды К-строка и В-строка— это значения параметра <конструктор строки> (приложение А), представляющие соответственно всю строку таблицы А и всю строку таблицы В.

7.12. Вот несколько таких формулировок. Заметьте, что этот список далеко не исчерпы- вающий [4.18]. Обратите внимание также на простоту каждого запроса!

SELECT DISTINCT S.SNAME FROM S WHERE S.St IN

( SELECT SP.St FROM SP

WHERE SP.Pt = 'P2' ) ;

SELECT DISTINCT T.SNAME

FROM ( S NATURAL JOIN SP ) AS T

WHERE T.Pt = 'P2' ;

SELECT DISTINCT T.SNAME

FROM ( S JOIN SP ON S.St = SP.Pt AND SP.Pt = 'P2' ) AS T ;

SELECT DISTINCT T.SNAME

FROM ( S JOIN SP USING St ) AS T

WHERE T.Pt = 'P2' ;

SELECT DISTINCT S.SNAME FROM S WHERE EXISTS ( SELECT * FROM SP

WHERE SP.Si = S.Sf AND SP.Pi = 'P2' ) ;

SELECT DISTINCT S.SNAME FROM S, SP WHERE S.SI = SP.Si AND SP.Pi = 'P2' ;

SELECT DISTINCT S.SNAME FROM S WHERE 0 <

( SELECT COUNT(*) FROM SP

WHERE SP.Si = S.SI AND SP.Pi = 'P2' ) ;

SELECT DISTINCT S.SNAME FROM S WHERE 'P2' IN

( SELECT SP.Pi FROM SP

WHERE SP.SI = S.St ) ; SELECT S.SNAME FROM S, SP WHERE S.St = SP.St AND SP.PI = 'P2' GROUP BY S.SNAME ;

Дополнительный вопрос. Каков смысл всех приведенных выше запросов?

7.13. Мы перенумеровали решения для этого пункта как ТЛЗ.п, где п — номер исходно­го упражнения в главе 6, т.е. упр. б.п. Подразумевается, что переменные SX, SY, РХ, PY, JX, JY, SPJX, SPJY и т.д. — это переменные кортежей, изменяющихся на отно­шениях S, Р, J и SPJ соответственно. Определение этих переменных кортежей в от­ветах не показано.

7.13.13. JX

7.13.14.JX WHERE JX.CITY = 'London'

7.13.15.SPJX.S# WHERE SPJX.Jt = Jl ( 'Jl' )

7.13.16.SPJX WHERE SPJX.QTY > QTY ( 300 ) AND SPJX.QTY < QTY ( 750 )

7.13.17. ( PX.COLOR, PX.CITY )

7.13.18. ( SX.Sf, PX.Pt, JX.Jt ) WHERE SX.CITY = PX.CITY

AND PX.CITY = JX.CITY AND JX.CITY = SX.CITY

7.13.19. ( SX.Sf, PX.Pt, JX.Jt ) WHERE SX.CITY * PX.CITY

OR PX.CITY Ф JX.CITY OR JX.CITY Ф SX.CITY

7.13.20. ( SX.Si, PX.Pt, JX.Jt ) WHERE SX.CITY Ф PX.CITY

AND PX.CITY Ф JX.CITY AND JX.CITY Ф SX.CITY

7.13.21.SPJX.Pf WHERE EXISTS SX ( SX.St = SPJX.St AND

SX.CITY = 'London' )

7.13.22.SPJX.Pf WHERE EXISTS SX EXISTS JX

{ SX.Sf = SPJX.St AND SX.CITY = 'London' AND JX.Jf = SPJX.Jf AND JX.CITY = 'London' )

7.13.23. ( SX.CITY AS SCITY, JX.CITY AS JCITY )

WHERE EXISTS SPJX ( SPJX.St = SX.St AND SPJX.Jf = JX.Jf )

7.13.24.SPJX.Pf WHERE EXISTS SX EXISTS JX

( SX.CITY = JX.CITY AND SPJX.St = SX.Sf AND SPJX.Jf = JX.Jt )

7.13.25.SPJX.Jf WHERE EXISTS SX EXISTS JX

( SX.CITY Ф JX.CITY AND SPJX.St = SX.Sf AND SPJX.Jf = JX.Jt )

7.13.26. ( SPJX.Pf AS XPf, SPJY.Pf AS YPf )

WHERE SPJX.St = SPJY.Sf AND SPJX.Pf < SPJY.Pf

7.13.27.COUNT ( SPJX.Jf WHERE SPJX.St = Si ( 'SI' ) ) AS N

7.13.28.SUM ( SPJX WHERE SPJX.St = St ( 'SI' )

AND SPJX.Pf = Pf ( 'Pi' ), QTY ) AS Q

Замечание. Следующее "решение" не верно (почему?).

SUM ( SPJX.QTY WHERE SPJX.St = St ( 'SI' )

AND SPJX.Pf = Pt ( 'PI' ), QTY ) AS Q

Ответ. При вычислении суммы повторяющиеся значения в столбце QTY буду: игнорироваться.

7.13.29. ( SPJX.Pf, SPJX.Jf,

SUM ( SPJY WHERE SPJY.Pf = SPJX.Pf

AND SPJY.Jf = SPJX.Jf, QTY ) AS Q )

7.13.30.SPJX.Pf WHERE

AVG ( SPJY WHERE SPJY.Pf = SPJX.Pf

AND SPJY.Jf = SPJX.Jf, QTY ) > QTY ( 350 )

7,13.31.JX.JNAME WHERE EXISTS SPJX ( SPJX.Ji = JX.Jl AND

SPJX.Si = S ( 'SI' ) )

7.13.32.PX.COLOR WHERE EXISTS SPJX ( SPJX.Pi = PX.Pi AND

SPJX.Si = Si ( 'SI' ) )

7.13.33.SPJX.Pi WHERE EXISTS JX ( JX.CITY = 'London' AND

JX.Ji = SPJX.Ji )

7.13.34.SPJX.Ji WHERE EXISTS SPJY ( SPJX.Pi = SPJY.Pi AND

SPJY.Si = Si ( 'SI' ) )

7.13.35.SPJX.Si WHERE EXISTS SPJY EXISTS SPJZ EXISTS PX , ( SPJX.Pi = SPJY.Pi AND SPJY.Si = SPJZ.S| AND SPJZ.Pi = PX.Pi AND PX.COLOR = COLOR ( 'Red' ) )

7.13.36.SX.Si WHERE EXISTS SY ( SY.Si = Si { 'SI' ) AND

SX.STATUS < SY.STATUS )

7.13.37.JX.Ji WHERE FORALL JY ( JY.CITY > JX.CITY ) или JX.Ji WHERE JX.CITY = MIN ( JY.CITY )

7.13.38.SPJX.Ji WHERE SPJX.Pi = Pi ( 'PI' ) AND

AVG ( SPJY WHERE SPJY.Pi = Pi ( 'PI' )

AND SPJY.Ji = SPJX.Ji, QTY ) > MAX ( SPJZ.QTY WHERE SPJZ.Ji = Ji ( 'Jl' ) )

7.13.39.SPJX.Si WHERE SPJX.Pi = Pi ( 'PI' ) AND SPJX.QTY > AVG ( SPJY

WHERE SPJY.Pi = Pi ( 'PI' ) AND SPJY.Ji = SPJX.Ji, QTY )

7.13.40.JX.Ji WHERE NOT EXISTS SPJX EXISTS SX EXISTS PX ( SX.CITY = 'London' AND PX.COLOR = COLOR ( 'Red' ) AND SPJX.Si = SX.Si AND SPJX.Pi = PX.Pi AND

SPJX.Ji = JX.Ji )

7.13.41.JX.Ji WHERE FORALL SPJY ( IF SPJY.Ji = JX.Ji

THEN SPJY.Si = Si ( 'SI' ) END IF j

7.13.42.PX.Pi WHERE FORALL JX

( IF JX.CITY = 'London' THEN EXISTS SPJY ( SPJY.Pi = PX.Pi AND SPJY.Ji = JX.Ji )

END IF )

7.13.43.SX.Si WHERE EXISTS PX FORALL JX EXISTS SPJY ( SPJY.Si = SX.Si AND

SPJY.Pi = PX.Pt AND SPJY.Jt = JX.Jt j

7.13.44.JX.Jt WHERE FORALL SPJY ( IF SPJY.St = Sf ( 'SI' ) THEN

EXISTS SPJZ ( SPJZ.Ji = JX.Jf AND SPJZ.Pf = SPJY.Pf ) END IF }

7.13.45.RANGEVAR VX RANGES OVER

( SX.CITY ), ( PX.CITY ), ( JX.CITY ) ;

VX.CITY

7.13.46.SPJX.Pf WHERE EXISTS SX ( SX.St = SPJX.St AND

SX.CITY = 'London' ) OR EXISTS JX ( JX.Jf = SPJX.Jf AND JX.CITY = 'London' )

7.13.47. ( SX.St, PX.Pt }

WHERE NOT EXISTS SPJX ( SPJX.St = SX.Sf AND

SPJX.Pf = PX.Pt )

7.13.48. ( SX.Sf AS XSt, SY.Sf AS YSf } WHERE FORALL PZ

( { IF EXISTS SPJX ( SPJX.St = SX.Sf AND

SPJX.Pf = PZ.Pf ) THEN EXISTS SPJY ( SPJY.Sf = SY.Sf AND SPJY.Pf = PZ.Pf )

END IF )

AND

( IF EXISTS SPJY ( SPJY.Sf = SY.Sf AND SPJY.Pf = PZ.Pf ) THEN EXISTS SPJX ( SPJX.St = SX.St AND SPJX.Pf = PZ.Pf )

END IF ) )

7.13.49.( SPJX.St, SPJX.Pf, ( SPJY.Jf, SPJY.QTY WHERE

SPJY.Sf = SPJX.St AND SPJY.Pf = SPJX.Pf ) AS JQ )

7.13.50. Пусть R — это результат вычисления выражения из ответа к предыдущему уп ражнению. Тогда имеем следующее.

RANGEVAR RX RANGES OVER R , RANGEVAR RY RANGES OVER RX.JQ ;

(RX.St, RX.Pf, RY.Jf, RY.QTY )

Мы несколько расширили синтаксис и семантику параметра <определени переменной кортежа>. Идея состоит в том, что определение переменной RY зави сит от переменной RX (обратите внимание на то, что оба определения разделеш запятыми, а не точками с запятыми, и поэтому связаны в одну операцию). Даль нейшее обсуждение этого вопроса приводится в [3.3].

7.14. Мы перенумеровали решения для этого пункта в виде 7Л4.п, где п— номер ис­ходного упражнения в главе 6, т.е. упр. б.и. Относительно определения и именова­ния переменных доменов будем следовать соглашениям, принятым в разделе 7.6.

7.14.13. ( JX, NAMEX, CITYX )

WHERE J ( Jf:JX, JNAME:NAMEX, CITY:CITYX )

7.14.14. ( JX, NAMEX, 'London' AS CITY )

WHERE J ( Jf:JX, JNAME:NAMEX, CITY:'London' )

7.14.15.SX WHERE SPJ ( S#:SX, J|:Jf ( 'Jl' ) )

7.14.16. ( SX, PX, JX, QTYX )

WHERE SPJ ( Sf:SX, P|:PX, Jf:JX, QTY:QTYX } AND QTYX > QTY ( 300 ) AND QTYX < QTY ( 750 )

  1. ( COLORX, CITYX WHERE P ( COLOR:COLORX, CITY:CITYX ) )

  2. ( SX, PX, JX ) WHERE EXISTS CITYX

{ S ( Si:SX, CITY:CITYX ) AND P ( Pl:PX, CITY:CITYX ) AND J ( Jl:JX, CITY:CITYX ) }

7.14.19. { SX, PX, JX )

WHERE EXISTS CITYX EXISTS CITYY EXISTS CITYZ { S ( Si:SX, CITY:CITYX ) AND P ( Pi:PX, CITY:CITYY ) AND J { Ji:JX, CITY:CITYZ ) AND ( CITYX Ф CITYY OR CITYY Ф CITYZ OR CITYZ Ф CITYX ) )

7.14.20. ( SX, PX, JX )

WHERE EXISTS CITYX EXISTS CITYY EXISTS CITYZ ( S ( Sl:SX, CITY:CITYX ) AND P { P#:PX, CITY:CITYY ) AND J ( J#:JX, CITY:CITYZ ) AND { CITYX Ф CITYY AND CITYY Ф CITYZ AND CITYZ Ф CITYX ) )

7.14.21.PX WHERE EXISTS SX ( SPJ ( P|:PX, S|:SX J AND

S ( Si:SX, CITY:'London' ) )

7.14.22.PX WHERE EXISTS SX EXISTS JX

( SPJ ( Si:SX, P#:PX, Ji:JX ) AND S ( Si:SX, CITY:'London' ) AND J ( J|:JX, CITY:'London' )

7.14.23. ( CITYX AS SCITY, CITYY AS JCITY ) WHERE EXISTS SX EXISTS JY

( S ( Si:SX, CITY:CITYX )

AND J ( Ji:JY, CITY:CITYY ) AND SPJ ( St:SX, J|:JY ) )

7.14.24.PX WHERE EXISTS SX EXISTS JX EXISTS CITYX ( S ( St;SX, CITYiCITYX ) AND J ( Ji-.JY, CITYtCITYX ) AND SPJ ( Si:SX, Pi:PX, Ji:JX ) )

7.14.25.JY WHERE EXISTS SX EXISTS CITYX EXISTS CITYY ( SPJ ( Si:SX, J|:JY ) AND S ( Sf:SX, CITY:CITYX } AND J ( Ji:JY, CITY:CITYY ) AND CITYX Ф CITYY )

7.14.26. { PX AS XP|, PY AS YPt ) WHERE EXISTS SX

{ SPJ ( S|:SX, PfiPX } AND SPJ ( St:SX, Pi:PY ) AND PX < PY )

7.14.27-7.14.30. Решения опущены.

7.14.31.NAMEX WHERE EXISTS JX

( J ( Jt:JX, JNAME:NAMEX ) AND SPJ ( S#:S# ( 'SI' ), Jt:JX ) )

7.14.32.COLORX WHERE EXISTS PX

( P ( Pt:PX, COLOR:COLORX ) AND SPJ { S#:S# { 'SI' ), PI:PX J )

7.14.33. PX WHERE EXISTS JX

( SPJ ( Pf:PX, Ji:JX ) AND J ( Ji:JX, CITY:'London' ) )

7.14.34.JX WHERE EXISTS PX

{ SPJ ( Pi:PX, Jl:JX ) AND SPJ ( P|:PX, Si:Si( 'SI' ) ) }

7.14.35. SX WHERE EXISTS PX EXISTS SY EXISTS PY

( SPJ ( Si:SX, Pi:PX ) AND

SPJ ( Pi-.PX, S#:SY ) AND

SPJ ( Si:SY, P#:PY ) AND

P ( Pi:PY, COLOR:COLOR ( 'Red' ) ) )

7.14.36. SX WHERE EXISTS STATUSX EXISTS STATUSY

{ S ( Sl:SX, STATUS:STATUSX ) AND S ( St:SI ( 'SI' ), STATUS:STATUSY J AND STATUSX < STATUSY )

7.14.37. JX WHERE EXISTS CITYX

{ J ( Jl:JX, CITY:CITYX ) AND FORALL CITYY ( IF J { CITY:CITYY } THEN CITYY > CITYX END IF) )

7.14.38-7.14.39. Решения опущены.

7.14.40. JX WHERE J ( Jt:JX ) AND

NOT EXISTS SX EXISTS PX

( SPJ ( Sf:SX, Pi:PX, Jt;JX ) AND S ( St:SX, CITY:'London' } AND P ( Pi:PX, COLOR:COLOR ( 'Red' ) ) )

7.14.41. JX WHERE J ( Ji:JX )

AND FORALL SX ( IF SPJ ( Sf:SX, Ji:JX ) THEN SX = Si ( 'SI' ) END IF )

7.14.42. PX WHERE P ( Pf:PX )

AND FORALL JX ( IF J ( J|:JX, CITY;'London' ) THEN SPJ ( Pi:PX, Ji:JX ) END IF )

7.14.43. SX WHERE S ( St:SX )

AND EXISTS PX FORALL JX

( SPJ ( Si:SX, P|:PX, J|:JX ) )

7.14.44. JX WHERE J ( J|:JX )

AND FORALL PX ( IF SPJ ( S|:Sl ( 'SI' ), Pt:PX ) THEN SPJ ( Pf:PX, Ji:JX ) END IF )

7.14.45.CITYX WHERE EXISTS S ( CITYtCITYX ) OR P ( CITY:CITYX )

OR J ( CITY:CITYX }

7.14.46.PX WHERE EXISTS SX ( SPJ ( Sl:SX, P|:PX ) AND

S ( Si:SX, CITY:'London' ) ) OR EXISTS JX ( SPJ ( Ji:JX, P|:PX ) AND

J ( Jt:JX, CITY:'London' ) )

7.14.47. ( SX, PX ) WHERE S ( Si:SX ) AND P ( Pi:PX )

AND NOT SPJ { Sl:SX, Pi:PX )

7.14.48. ( SX AS XSi, SY AS YSi )

WHERE S { Sl:SX ) AND S ( S|:SY ) AND FORALL PZ

( ( IF SPJ ( S|:SX, Pf:PZ ) THEN SPJ ( S|:SY, P|:PZ ) END IF ) AND

( IF SPJ ( Si:SY, P#:PZ ) THEN SPJ ( S#:SX, PfhPZ ) END IF ) )

7.14.49-7.14.50. Решения опущены.

7.15. Мы перенумеровали решения этого пункта в виде 7.15.и, что соответствует номе­рам 6.и в исходных упражнениях главы 6.

7.15.13. SELECT * FROM J ;

или просто

TABLE J ;

  1. select from where

  2. select from where

  3. select from where and

  4. select from

  5. select from where and

  6. select from where

  7. select from where and and

  8. select from where

7.15.22. select from where

and

7.15.23. select from where

j.* j

j.city = 'London' ;

distinct spj.Sf spj

spj.Ji = 'Jl' ;

spj. * spj

spj.qty >= 300 spj.qty <= 750 ;

distinct p.color, p.city p ;

s.SI, p.Pi, j.Ji s, p, j

s.city = p. city p.city = j. city ;

s.si, p.Pi, j.Ji

s, p, j

not ( s.city = p.city and p.city = j.city ) ;

S.si, p.Pi, J.Ji

s, p, j

s.city <> p.city p.city <> j.city j.city <> p.city ;

distinct spj.Pi spj

( select s.city from s

where s.SI = spj.Si ) = 'London' ;

distinct spj.Pi spj

( select s.city from s

where s.SI = spj.Si } = 'London' ( select j.city from j

where j.Ji = spj.Ji ) = 'London' ;

distinct s.city as scity, j.city as jcity s, j exists select * from spj

WHERE SPJ.St = AND SPJ.Jt =

S.Sf

J.Jt } ;

7.15.24. SELECT DISTINCT FROM SPJ WHERE ( SELECT

SPJ.Pf

S.CITY

FROM S

WHERE S.St = SPJ.St ) = { SELECT J.CITY FROM J

WHERE J.Jt = SPJ.Jt ) ;

7.15.25. SELECT FROM WHERE

DISTINCT SPJ

( SELECT

SPJ.Jt

S.CITY

FROM S

WHERE S.St = SPJ.St ) <> ( SELECT J.CITY FROM J

WHERE J.Jt = SPJ.Jt ) ;

7.15.26.SELECT DISTINCT SPJX.Pf AS PA, SPJY.Pf AS PB FROM SPJ AS SPJX, SPJ AS SPJY WHERE SPJX.St = SPJY.Sf AND SPJX.Pf < SPJY.Pf ;

7.15.27.SELECT COUNT ( DISTINCT SPJ.Jt ) AS N FROM SPJ

WHERE SPJ.St = 'SI' ;

7.15.28.SELECT SUM ( SPJ.QTY } AS X FROM SPJ WHERE SPJ.St = 'SI' AND SPJ.Pf = 'PI' ;

7.15.29.SELECT SPJ.Pf, SPJ.Jt, SUM ( SPJ.QTY ) AS Y FROM SPJ

GROUP BY SPJ.Pf, SPJ.Jt ;

7.15.30.SELECT DISTINCT SPJ.Pf FROM SPJ

GROUP BY SPJ.Pf, SPJ.Jt HAVING AVG ( SPJ.QTY ) > 350 ;

7.15.31.SELECT DISTINCT J.JNAME

FROM J, SPJ

WHERE J.Jt = SPJ.Jt

AND SPJ.St = 'SI' ;

7.15.32.SELECT DISTINCT P.COLOR FROM P, SPJ WHERE P.Pt = SPJ.Pf AND SPJ.St = 'SI' ;

7.15.33.SELECT DISTINCT SPJ.Pf FROM SPJ, J WHERE SPJ.Ji = J.Ji AND J.CITY = 'London' ;

7.15.34.SELECT DISTINCT SPJX.Ji

FROM SPJ AS SPJX, SPJ AS SPJY WHERE SPJX.Pi = SPJY.Pi AND SPJY.Si = 'SI' ;

7.15.35.SELECT DISTINCT SPJX.Si

FROM SPJ AS SPJX, SPJ AS SPJY, SPJ AS SPJZ WHERE SPJX.Pi = SPJY.Pi AND SPJY.Si = SPJZ.Si AND { SELECT P.COLOR

FROM P

WHERE P.Pi = SPJZ.Pi ) = 'Red' ;

7.15.36.SELECT S.St FROM S

WHERE S.STATUS < { SELECT S.STATUS

FROM S

WHERE S.Si = 'SI' ) ;

7.15.37.SELECT J.Ji FROM J

WHERE J.CITY = { SELECT MIN ( J.CITY )

FROM J ) ;

7.15.38.SELECT DISTINCT SPJX.Ji FROM SPJ AS SPJX WHERE SPJX.Pi = 'PI' AND ( SELECT AVG ( SPJY.QTY )

FROM SPJ AS SPJY WHERE SPJY.Ji = SPJX.Ji AND SPJY.Pi = 'PI' ) > ( SELECT MAX ( SPJZ.QTY ) FROM SPJ AS SPJZ WHERE SPJZ.Ji = 'Jl' ) ;

7.15.39.SELECT DISTINCT SPJX.Si FROM SPJ AS SPJX WHERE SPJX.Pt = 'PI'

AND SPJX.QTY > ( SELECT AVG ( SPJY.QTY )

FROM SPJ AS SPJY

WHERE SPJY.Pi = 'PI'

AND SPJY.Ji = SPJX.Ji ) ;

7.15.40. SELECT FROM WHERE

J.Ji J

NOT EXISTS

( SELECT *

FROM SPJ, P, S

WHERE SPJ.Jt = J.Jt

AND SPJ.Pf = P.Pt

AND SPJ.St = S.Sf

AND P.COLOR = 'Red'

AND S.CITY = 'London' ) ;

7.15.41.SELECT J.Jt FROM J

WHERE NOT EXISTS { SELECT * FROM SPJ

WHERE SPJ.Jt = J.Jt

AND NOT ( SPJ.St = 'SI' ) ) ;

7.15.42.SELECT P.Pt FROM P

WHERE NOT EXISTS ( SELECT * FROM J

WHERE J.CITY = 'London'

AND NOT EXISTS ( SELECT * FROM SPJ WHERE SPJ.Pf = P.Pt AND SPJ.Jt = J.Jt ) ) ;

7.15.43.SELECT S.Sf FROM S WHERE EXISTS ( SELECT * FROM P

WHERE NOT EXISTS ( SELECT * FROM J

WHERE NOT EXISTS ( SELECT * FROM SPJ WHERE SPJ.St = S.St AND SPJ.Pf = P.Pt AND SPJ.Jt = J.Jt ) ) ) ;

7.15.44.SELECT J.Jt FROM J

WHERE NOT EXISTS ( SELECT * FROM SPJ AS SPJX WHERE SPJX.St = 'SI' AND NOT EXISTS

( SELECT *

FROM SPJ AS SPJY

WHERE SPJY.PI = SPJX.PI

AND SPJY.Ji = J.JI ) ) ;

7.15.45.SELECT S.CITY FROM S UNION

SELECT P.CITY FROM P UNION

SELECT J.CITY FROM J ;

7.15.46.SELECT DISTINCT SPJ.Pi FROM SPJ

WHERE ( SELECT S.CITY FROM S

WHERE S.SI = SPJ.Si ) = 'London' OR ( SELECT J.CITY FROM J

WHERE J.Ji = SPJ.Ji ) = 'London' ;

7.15.47.SELECT S.SI, P.Pi

FROM S CROSS JOIN P EXCEPT

SELECT SPJ.Si, SPJ.PI

FROM SPJ ;

7.15.48. Решение опущено.

7.15.49-7.15.50. Решений не существует.

Глава

Целостность данных

8.1. Введение

Термин целостность данных используется для описания точности и корректности хранящейся в базе информации. Как отмечалось в главе 3, в базе данных может сущест­вовать любое количество ограничений целостности и в общем случае они могут быть произвольной сложности. Например, для базы данных поставщиков и деталей можно предположить, что номера поставщиков должны представляться в виде 'Snnnn' (где пппп — десятичное число, не превышающее 9999) и иметь уникальные значения; значе­ния статуса поставщика должны находиться в диапазоне от 1 до 100, причем поставщики из Лондона должны иметь статус 20; количество поставляемых деталей должно быть кратно 50, причем красные детали должны храниться только в Лондоне; и т.д. В общем случае можно сделать заключение, что СУБД должно быть известно о подобных ограни­чениях и, безусловно, необходимо, чтобы СУБД тем или иным образом обеспечивала их выполнение (в основном, посредством отмены любых обновлений, нарушающих эти требования). Рассмотрим следующий пример (снова воспользуемся языком Tutorial D).

CONSTRAINT SC3

IS_EMPTY ( S WHERE STATUS < 1 OR STATUS > 100 ) ;

Смысл этого выражения таков: "Значения статуса поставщика должны находиться в диапазоне от 1 до 100". Обратите внимание на имя ограничения— SC3 (т.е. "Ограничение № 3 для поставщиков"). Под этим именем данное ограничение будет заре­гистрировано в системном каталоге и именно это имя будет указываться в диагностиче­ских сообщениях системы при обнаружении попыток нарушения данного ограничения. Само ограничение задается в виде логического выражения, результат вычисления кото­рого не должен иметь значение ложь (false).

Замечание. Для определенности здесь мы используем алгебраическую версию языка Tutorial D, поэтому логическое выражение часто будет принимать форму IS_EMPTY(...), которая означает, что в базе данных нет данных, нарушающих указанное ограничение (см. раздел 6.9 главы 6). Аналог приведенного выше примера в виде выражения реляци­онного исчисления может выглядеть следующим образом1.

CONSTRAINT SC3

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


FORALL SX ( SX.STATUS > 1 AND SX.STATUS < 100 ) ;

Здесь SX — переменная кортежа, которая изменяется на отношении поставщиков S.

По ходу отметим, что логическое выражение в ограничениях, представленных в виде выражений реляционного исчисления, должно быть закрытой формулой WFF (см. раз­дел 7.2 главы 7) и чаще всего будет иметь форму FORALL х(...}. Следовательно, выраже­ние в данном примере означает, что все значения статуса поставщиков должны нахо­диться в указанном диапазоне. На практике, конечно, достаточно, чтобы система просто проверяла лишь вновь вводимые или обновляемые значения статуса поставщиков, а не все те значения, которые уже хранятся в базе данных.

После того как новое ограничение будет объявлено, необходимо, чтобы оно было проверено системой, т.е. нужно убедиться, что база данных в текущий момент удовле­творяет вновь установленному ограничению. Если это не так, новое ограничение отвер­гается; в противном случае оно принимается (т.е. сохраняется в каталоге) и с этого мо­мента вступает в силу. Объявление в системе приведенного выше ограничения приведет к тому, что СУБД будет контролировать все операции, которые подразумевают вставку кортежа для нового поставщика или изменение статуса существующего поставщика.

Конечно, дополнительно требуется, чтобы существовала возможность отмены уста­новленного ранее ограничения.

DROP CONSTRAINT <имя ограничение ;

Например:

DROP CONSTRAINT SC3 ;

Замечание. Как вы, наверное, уже заметили, наше обсуждение сосредоточено на декларативной поддержке ограничений целостности. К сожалению, на сегодняшний день лишь немногие продукты предоставляют что-либо существенное в плане реали­зации такой поддержки, хотя ситуация в этом направлении пусть медленно, но все же улучшается. В некоторых продуктах (особенно в нереляционных) практикуется совсем другой подход, т.е. применяется процедурная поддержка ограничений целостности, построенная на использовании хранимых, или триггерных, процедур2. Однако мож­но предположить, что если бы существующие СУБД действительно предоставляли не­обходимую декларативную поддержку, то по крайней мере 90% текста определений типичной базы данных составляли бы объявления ограничений целостности данных. Таким образом, предоставляющая подобную поддержку система значительно облегчи­ла бы труд прикладных программистов и позволила бы существенно повысить произ­водительность их труда. Декларативная поддержка ограничений целостности является очень важным аспектом СУБД.

Хранимые, или триггерные, процедуры — это заранее скомпилированные процедуры, кото­рые могут вызываться из прикладных программ. В качестве примера можно упомянуть опреде­ленные пользователем операторы ABS, DIST, REFLECT и т.д., которые рассматривались в разде­ле 5.2 (подраздел "Объявление оператора"). Такие процедуры логически можно рассматривать как расширение СУБД (в системах клиент/сервер они чаще всего хранятся и выполняются на сервере). Мы еще поговорим об этих процедурах в разделе 8.8, в аннотациях к некоторым публи­кациям в конце данной главы, а также в главе 20.

Прежде чем перейти к следующему вопросу, отметим, что в реляционной мо­дели на протяжении последних лет точка зрения на проблему поддержки целост­ности данных претерпевает изменения в большей степени, чем другие (пожалуй,

точнее будет сказать, эволюционирует). Как отмечалось в главе 3, изначально ак­цент делался на первичных и внешних ключах (для краткости — просто на "ключах"). Однако со временем особое — даже ключевое! — значение ограниче­ний целостности в общей картине осознавалось во все большей степени и оцени­валось все выше. Одновременно начали возникать некоторые щекотливые вопро­сы, в частности относительно ключей. Структура этой главы отражает такое сме­щение акцентов, поскольку в начале (и еще в нескольких разделах) рассматрива­ется общая проблема ограничений целостности, а затем — ключи, которые по-прежнему имеют большое практическое значение.

Схема классификации ограничений

В [3.3] ограничения целостности классифицируются по четырем основным категори­ям: ограничения типа (домена), атрибута, переменной-отношения и базы данных.

  • В ограничениях типа задаются допустимые значения для данного типа.

  • Замечание. В этой главе под типом подразумевается скалярный тип. Типы отно­шений, конечно, также являются объектами ограничений типов, но они представ­ляют собой, по существу, просто логическое следствие ограничений типа, которые применяются к скалярным типам и в терминах которых эти типы отношений в ко­нечном счете определены.

  • В ограничениях целостности атрибута задаются допустимые значения для дан­ного атрибута.

  • В ограничениях целостности переменной-отношения задаются допустимые значе­ния для данной переменной-отношения.

  • В ограничениях целостности базы данных задаются допустимые значения для этой базы данных.

Подробнее указанные виды ограничений рассматриваются в разделах 8.2-8.5 соот­ветственно.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]