Третий манифест Кристофера Дейта и Хью Дарвена

         

Формальные определения


Формальные определения

Поскольку этот раздел носит очень формальный характер, Д&Д начинают его с повтора некоторых необходимых определений. Пусть r - отношение, A - имя атрибута r, T - тип атрибута A, v - значение типа T. Тогда:

Заголовок Hr отношения r - это множество упорядоченных пар вида <A, T>, по одной такой паре для каждого атрибута A r. По определению никакие две пары в этом множестве не могут содержать одно и то же имя атрибута A. Пусть tr - это кортеж, соответствующий Hr; т.е. tr - это множество упорядоченных кортежей вида <A, T, v> по одному такому кортежу для каждого атрибута A Hr. Тело Br отношения r - это множество таких кортежей tr. Заметим, что в общем случае могут существовать такие кортежи tr, соответствующие Hr, но не появляющиеся в Br.

Заметим, что заголовок - это множество, тело - это множество, и кортеж - это множество. Элемент заголовка - это упорядоченная пара вида <A, T>; элемент тела - это кортеж; элемент кортежа - это упорядоченный триплет вида <A, T, v>. Любое подмножество заголовка - это заголовок, любое подмножество тела - это тело, и любое подмножество кортежа - это кортеж.

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

Пусть s есть >NOT< r.

Hs = Hr

Bs = { ts : exists tr ( tr П Br and ts = tr ) }

Операция >NOT< производит дополнение s заданного отношения r. Заголовком s является заголовок r. Тело s включает все кортежи с этим заголовком, не входящие в тело r.

Пусть s есть r >REMOVE< A. Требуется, чтобы существовал некоторый тип T такой, что <A,T> Hr.

Hs = Hr minus { <A,T> }

Ds = { ts : exists tr exists v

            ( tr Br and v T and <A,T,V> tr and ts = tr minus { <A,T,v> } ) }


Операция >REMOVE< производит отношение s, формируемое путем удаления указанного атрибута A из данного отношения r. Операция эквивалентна взятию проекции r на все атрибуты, кроме A. Заголовок s получается вычитанием из заголовка r пары <A,T>. Тело s состоит из таких кортежей, которые соответствуют заголовку и каждый из которых является подмножеством некоторого кортежа r.

Пусть s есть r >RENAME< (A, B). Требуется, чтобы существовал некоторый тип T такой, что <A,T> Hr и чтобы не существовал какой-либо тип T такой, что

<B,T> Hr. Hs = ( Hr minus { <A,T> } ) union { <B,T> } Bs = { ts : exists tr exists v ( tr Br and v T and <A,T,v> tr and ts = ( tr minus { <A,T,v> } ) union { <B,T,v> } )

Операция >RENAME< производит отношение s, которое отличается отзаданного отношения r только именем одного атрибута, которое изменяется с A на B. Заголовок s такой же, как заголовок r за исключением того, что пара <A,T> заменяется на пару <B,T>. Тело s включает все кортежи тела r, но в каждом из этих кортежей триплет <A,T,v> заменяется на триплет <B,T,v>.

Пусть s есть r1 >AND< r2. Требуется, что если <A,T1> Hr1 и <A,T2> Hr2, то должно быть T1 = T2.

Hs = Hr1 union Hr2 Bs = { ts : exists tr1 exists tr2 ( ( tr1 Br1 and tr2 Br2 ) and ts = tr1 union tr2 ) }



Операция >AND< является реляционной конъюнкцией, производящей результат, называвшийся ранее в литературе естественным соединением заданных отношений r1 и r2. Заголовок s является объединением заголовков r1 и r2. Тело s состоит из всех кортежей, соответствующих заголовку s и являющихся надмножеством некоторого кортежа из тела r1 и некоторого кортежа из тела r2. Операцию >AND< можно было бы логически назвать conjoin (конъюнктивным соединением).

Пусть s есть r1 >OR< r2. Требуется, что если <A,T1> Hr1 и <A,T2> Hr2, то должно быть T1 = T2.

Hs = Hr1 union Hr2 Bs = { ts : exists tr1 exists tr2 ( ( tr1 Br1 or tr2 Br2 ) and ts = tr1 union tr2 ) }



Операция >OR< является реляционной дизъюнкцией, являясь обобщением того, что ранее в литературе называлось объединением (в этом частном случае заданные отношения r1 и r2 имеют одинаковые заголовки, и результат s является объединением этих двух отношений в традиционном смысле). Заголовок s есть объединение заголовков r1 и r2. Тело s состоит из всех кортежей, соответствующих заголовку s и являющихся надмножеством либо некоторого кортежа из тела r1, либо некоторого кортежа из тела r2. Операцию >OR< можно было бы логически назвать disjoin (дизъюнктивным соединением).

Наконец, определим "макро"-операцию >COMPOSE<. Пусть s есть r1 >COMPOSE< r2 (r1 и r2 должны удовлетворять тем же требованиям, что и для >AND<). Пусть общими атрибутами для r1 и r2 являются A1, A2, …, An (n і 0). Тогда s определяется как результат выражения

( r1 >AND< r2 ) >REMOVE< An … >REMOVE< A2 >REMOVE< A1

При n = 0 r1 >COMPOSE< r2 - это то же самое, что r1 >AND< r2, что, в свою очередь, то же самое, что r1 TIMES r2 в алгебре Кодда.



Мотивация и обоснование


Мотивация и обоснование

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

Переменные, появляющиеся в предикатах, называются заменителями (placeholder). Заменители являются логическими переменными, а не переменными в смысле языка программирования, поэтому Д&Д предпочитают использовать другой термин. Для обозначения числа заменителей в предикате используются слова с греческим суффиксом -adic, а для обозначения степени отношения - слова с латинским суффиксом -ary. Например, предикат "Служащий E работает в отделе D" является диадным, а отношение, соответствующее этому предикату (см. RM-утверждение 10), - бинарным.

Разработка алгебры A мотивируется следующими целями:

По соображениям пcихологии Д&Д искали набор операций, для которых существуют непосредственные двойники в логике, и в меньшей степени опирались на теорию множеств. По мнению Д&Д, этот подход позволяет лучше осмыслять и понимать реляционную теорию. В предшествовавших алгебрах имелось более одной операции, соответствующей логической операции and. Эта избыточность казалась Д&Д неправильной, и они ее устранили. Д&Д хотели, чтобы реляционные операции Tutorial D отображались в выражения алгебры A. Детали этого отображения содержатся в пятой главе.

Вот более подробное обсуждение четырех принципиальных отличий A от предшествовавших алгебр.

Отсутствие TIMES

Когда в логике два предиката соединяются связкой and, нужно обращать внимание на имена заменителей. Любое имя заменителя, которое появляется в обоих предикатах, должно пониматься как обозначающее одно и то же в новообразованном предикате. Например, рассмотрим два предиката, выраженные на естественном языке: "Служащий E работает в отделе D" и "Служащий E работает над проектом J".
Связка этих двух предикатов с использованием and порождает триадный, а не тетрадный предикат: "Служащий E работает в отделе D и служащий E работает над проектом J". Этот предикат можно представить в сокращенной форме "Служащий E работает в отделе D над проектом J", чтобы подчеркнуть тот факт, что мы не можем подставить некоторого конкретного служащего для E, который работает в отделе D, не подставив того же служащего для E, работающего над проектом J. Это наблюдение позволяет заметить, что заменители тесно связаны с хорошо известной операцией естественного соединения и, конечно, с операцией >AND< алгебры A.

Что касается операции TIMES, она, конечно, является частным случаем соединения (>AND< в алгебре A). Более точно, TIMES соответствует связке через and двух предикатов без общих заменителей, например, "Служащий E работает в отделе D, и у проекта J имеется бюджет B".

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

Отсутствие UNION

Предикаты естественного языка могут комбинироваться не только с помощью and, но и с помощью or. Триадному предикату "Служащий E работает в отделе D или служащий E работает над проектом J" соответствует тернарное отношение. Если служащий EX работает в отделе DX, то кортеж (EX, DX, J) входит в тело этого отношения для всех возможных проектов J независимо от того, работает ли реально служащий EX над проектом J (и даже независимо от того, выполняется ли проект J в это время в компании). Аналогично, если служащий EX работает над проектом JX, то кортеж (EX, D, JX) входит в тело отношения для всех возможных отделов D независимо от того, работает ли реально служащий EX в отделе D (и даже независимо от того, существует ли отдел D в это время в компании).



Операция >OR< вводится в алгебру A как двойник операции or. Классическая операция UNION является частным случаем >OR< и соответствует связыванию через or двух предикатов, которые содержат в точности один и тот же набор заменителей, например, "Служащий E работает в отделе D или служащий E прикомандирован к отделу D".

Здесь и далее Д&Д умышленно оставляют в стороне вычислительные проблемы выполнения операции.

Отсутствие MINUS

Пусть WORKS_IN - это отношение с атрибутами E (служащий) и D (отдел), а соответствующий предикат - "Служащий E работает в отделе D". Тело логического дополнения (>NOT<) этого отношения состоит из всех возможных кортежей в форме (E, D), для которых неверно, что служащий E работает в отделе D.

Чтобы показать возможность устранения операции MINUS, рассмотрим следующий пример. Предположим, что в придачу к отношению WORKS_IN имеется отношение WORKS_ON с атрибутами E и J (проект), а соответствующий предикат - "Служащий E работает над проектом J". Рассмотрим теперь унарное отношение, соответствующее монадному предикату "Служащий E работает в некотором отделе, но не работает ни над каким проектом". К алгебре Кодда это отношение можно было бы получить, спроецировав отношения WORKS_IN и WORKS_ON на атрибут E и взяв затем соответствующую разность. В алгебре A мы сначала проецируем WORKS_ON на E, а затем берем >NOT< от этой проекции; соответствующим предикатом будет "Не существует такого проекта, над которым бы работал служащий E". Потом это отношение можно соединить (>AND<) с отношением WORKS_IN, и проекция этого соединения на E даст искомый результат.

Отсутствие restrict (WHERE), EXTEND и SUMMARIZE

При выполнении restrict (WHERE), EXTEND и SUMMARIZE требуются вызовы некоторых операций. В случае restrict эти операции возвращают значения (инстинностные значения), используемые для предотвращения появления некоторых кортежей в результирующем отношении; в случае EXTEND и SUMMARIZE операции возвращают значения, на основе которых определяются некоторые атрибуты результирующего отношения.



Для целей Д&Д имеет смысл и может быть полезно рассматривать такие операции как отношения. Рассмотрим операцию Op, являющуюся скалярной функции (операцию, возвращающую в точности один результат, являющийся скалярным значением). Предположим, что у Op имеется n параметров. Тогда можно трактовать Op как отношение с n+1 атрибутами, по одному на каждый параметр и один на результат. Конечно, атрибуты, соответствующие параметрам, образуют возможный ключ этого отношения; однако это возможный ключ может не быть единственным. Например, если PLUS - это отношение с атрибутами X, Y и Z, тип каждого из которых INTEGER, и это отношение соответствует скалярной функции "+" целой арифметики и предикату "X + Y = Z", то возможными ключами отношения являются комбинации {X, Y}, {X, Z} и {Y, Z}, а в тело отношения входит по одному кортежу (X, Y, Z) для всех возможных комбинаций X, Y, Z, удовлетворяющих предикату.

Замечание: По аналогии с relvar можно относиться к отношениям типа PLUS как к relcon, или как к реляционным константам: они именованы, но их значения не изменяются во времени. И, конечно, упоминавшиеся возможные ключи - это ключи реляционной константы, а не реляционной переменной.

Итак, скалярная функция является частным случаем отношения. Более точно, любой отношение можно рассматривать как операцию, отображающее некоторое подмножество его атрибутов на оставшиеся атрибуты; если это отображение является функциональным (много-к-одному), то отношение можно считать функцией. Поскольку у множества из n элементов имеется 2n подмножеств, отношение степени n можно считать представлением 2n различных операций, некоторые из которых функции, а некоторые - нет (в общем случае). Например, если рассматривать PLUS как операцию, отображающую Z в X и Y, то это отображение не функционально (не поддерживаются функциональные зависимости ZX и ZY), и соответствующая операция не является функцией.

В следующем разделе показывается, что при подобной трактовке операций и наличии операций алгебры A >AND<, >REMOVE< и >RENAME< можно отказаться от непосредственной поддержки операций restrict, EXTEND и SUMMARIZE.



Новая реляционная алгебра


Новая реляционная алгебра

Введение

В четвертой главе предлагается новая реляционная алгебра, которую Дейт и Дарвен (Д&Д) называют A - двойной рекурсивный акроним от ALGEBRA, что, в свою очередь, раскрывается в "A Logical Genesis Explains Basic Relational Algebra". Основная цель, которая преследовалась при разработке алгебры A, состояла в том, чтобы более четко показать связь этой дисциплины с логикой первого порядка.

Алгебра A отличается от оригинальной алгебры Кодда четырьмя основными аспектами:

Операция декартова произведения (TIMES) заменена операцией естественного соединения, которую, подчеркивая наличие двойника этой операции в логике предикатов, Д&Д называют просто >AND<. TIMES становится частным случаем >AND<. Замечание: имена операций алгебры A обрамляются символами ">" и "<", чтобы отличать их от соответствующих имен операций логики предикатов и Tutorial D. Имя >AND< не должно вводить в заблуждение, конечно, оно обозначает реляционную операцию (ее результатом является отношение), в то время как ее двойник из логики предикатов and является логической операцией (возвращает истинностное значение). Аналогичные замечания относятся и к операциям >OR< и >NOT<. Операция UNION заменена более общей операцией >OR<, для применения которой не требуется совпадение заголовков отношений-операндов. UNION становится частным случаем >OR<. В алгебру включена операция реляционного дополнения >NOT<. Наличие этой операции позволяет исключить операцию вычитания (MINUS), которая становится частным случаем комбинации >AND< и >NOT<. Д&Д обходятся без операций restrict (WHERE), EXTEND и SUMMARIZE, поскольку эти операции являются частным случаем >AND<.

Кроме перечисленных трех операций в состав алгебры A входят операции >RENAME<, >REMOTE< и >COMPOSE<, а также операция транзитивного замыкания >TCLOSE<.



Обращение с операциями как с отношениями


Обращение с операциями как с отношениями

Обратимся снова к отношению PLUS с целочисленными атрибутами X, Y и Z, соответствующему предикату "X + Y = Z". Пусть TWO_AND_TWO - это (уникальное) отношение, тело которого состоит из единственного кортежа

{ < X, INTEGER, 2 >, <Y, INTEGER, 2> }

Тогда выражение

TWO_AND_TWO >COMPOSE< PLUS

произведет отношение, тело которого состоит из единственного кортежа

{ < Z, INTEGER, 4> }

Тем самым, на самом деле была вызвана операция "+" с аргументами X = 2 и Y = 2, и был получен результат Z = 4 (заметим, что у результата имеется имя Z; Д&Д изучают возможные последствия этого для языка D). Конечно, этот результат является встроенным как значение атрибута внутри кортежа отношения. Чтобы извлечь результат в виде чистого скалярного значения, необходимо выйти за пределы алгебры A и применить операции (требуемые RM-утверждениями 7 и 6 соответственно) для (a) извлечения указанного кортежа из указанного отношения и (b) для извлечения значения указанного атрибута из указанного кортежа. В терминах языка TUTORIAL D эти извлечения можно выполнить следующим образом:

Z FROM ( TUPLE FROM ( result ) )

где result обозначает результат вычисления A-выражения TWO_AND_TWO >COMPOSE< PLUS.

Однако для целей этого раздела Д&Д интересуются обхождением с операциями как с отношениями в чисто реляционном контексте. В частности, этот подход позволяет объяснить суть классической реляционной операции EXTEND чисто реляционным образом.

Рассмотрим выражение TWO_AND_TWO >AND< PLUS.

Результатом этого выражения является отношение, тело которого состоит в точности из одного кортежа

{ < X, INTEGER, 2 >, < Y, INTEGER, 2 >, < Z, INTEGER, 2 > }

Следует отчетливо понимать, что это выражение A логически эквивалентно следующему расширению на языке TUTORIAL D:

EXTEND TWO_AND_TWO ADD X + Y AS Z

Этого примера достаточно, чтобы показать, каким образом можно отказаться от операции EXTEND.
Более того, то же самое выражение логически эквивалентно следующем ограничению на языке TUTORIAL D:

PLUS WHERE X = 2 AND Y = 2

Этого примера достаточно, чтобы показать, каким образом можно отказаться от restrict.

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

В конце раздела Д&Д отмечают, что не только со скалярными функциями можно обращаться как с отношениями. Вот примеры:

Пример скалярной операции, не являющейся функцией, представляет SQRT ("квадратный корень"). Для заданного положительного аргумента эта операция вырабатывает два различных значения. Например, SQRT(4.0) возвращает +2.0 и -2.0. Пример операции, являющейся функцией, но не скалярной, представляет ADDR_OF ("адрес"). Эта операция для заданного служащего возвращает адрес этого служащего в виде коллекции из четырех значений (STREET, CITY, STATE, ZIP).

Рассмотрим эти примеры немного глубже. Очевидно, что SORT можно воспринимать как отношение с атрибутами, например, X и Y типа RATIONAL. Но это отношение не является функцией, поскольку отсутствует функциональная зависимость YаX (например, одновременно присутствуют кортежи (4.0, +2.0) и (4.0, -2.0)). (С другой стороны, функциональная зависимость XаY поддерживается.) Это отношение содержит:

Для x = 0 ровно один кортеж с X = x; Для x > 0 ровно два кортежа с X = x; Для x < 0 ни одного кортежа с X = x.

Из этого следует, что выражение

SQRT >COMPOSE< { { < X, RATIONAL, 4.0 > } }

по сути дела представляет вызов операции SQRT, но при вызове образуются два результата. Более точно, производится унарное отношение со следующим телом:

{ { < Y, RATIONAL, +2.0 > },

     < Y, RATIONAL, -2.0 > } }

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

Очевидно, что можно обращаться как с отношением и с операцией ADDR_OF. Это отношение имело бы атрибуты E, STREET, CITY, STATE и ZIP, а атрибут E был бы возможным ключом. Поэтому выражение

{ { < E, EMPLOYEE, e > } } >COMPOSE< ADDR_OF

(e обозначает некоторого служащего) на самом деле представляет вызов операции ADDR_OF, возвращающий не скалярное значение. Одним из выводов Д&Д является то, что в языке D может оказаться разумным поддерживать расширенную форму EXTEND, не обязательно гарантирующей появление ровно одного дополнительного атрибута.



Очень строгие OO-суждения


Очень строгие OO-суждения

В языке D следует поддерживать некоторую форму наследования типов (см. OO-утверждения 2 и 3). В соответствии с этим суждением в языке D не следует поддерживать неявные преобразования типов.

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

Следует поддерживать генераторы типов коллекций, такие как LIST, ARRAY и SET, распространенные в языках с развитыми системами типов.

Для любого генератора типа коллекции С, отличного от RELATION, следует обеспечить операцию преобразования (скажем, C2R) для преобразования значений типа C в отношения и обратную операцию (скажем, R2C) таким образом, что:

C2R(R2C(r)) = r для любого выразимого r;

R2C(C2R(c)) = c для любого выразимого значения c типа C.

Следует основывать язык D на одноуровневой модели хранения.



Отрицательные OO-утверждения


Отрицательные OO-утверждения

Relvars - это не домены.

Никакое значение не должно обладать каким-либо ID, отличным от самого этого значения.

Как видно, это очередной "наезд" на объектно-ориентированный мир. Но утверждение не слишком корректное, поскольку в объектном мире никто и никогда не утверждал, что у значений должны существовать ID. Говорится про "object identity", то есть про существование уникальной идентификации объектов. Но Д&Д вообще не хотят соглашаться с наличием понятия объекта.

Очень строгие RM-суждения

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

В язык D следует включить некоторую декларативную сокращенную форму для выражения ссылочных ограничений (называемых также ограничениями внешнего ключа).

Если RX - реляционное выражение, то по определению RX можно считать обозначением relvar R -- либо определенной пользователем (если RX состоит только из имени relvar), либо определяемой системой (в противном случае). Желательно, хотя и не всегда возможно, чтобы система была в состоянии выводить возможные ключи R таким образом, что:

Если RX предназначено для определения выражения для некоторой виртуальной relvar R', то эти выводимые возможные ключи можно проверить на соответствие возможным ключам, явно определяемым для R'. Если конфликт не обнаруживается, то выводимые ключи становятся возможными ключами R';

Сведения о выводимых ключах могут быть включены в информацию об R, доступную пользователям языка D (через "метазапрос").

В языке D следует поддерживать такие возможности, но без какой-либо гарантии того, что a) эти выводимые ключи не составляют точного надмножества множества реальных возможных ключей и b) выводимый возможный ключ обнаружен для каждого реального возможного ключа.


В языке D следует поддерживать ограничения переходов, т.е. ограничения на допустимые изменения значений данных relvar или базы данных.

В языке D следует поддерживать некоторую сокращенную форму для выражения запросов с квотами. Для формулировки подобных запросов не должно требовать преобразование соответствующего отношения, например, в массив.

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

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

Для работы с "отсутствующей информацией" в языке D следует обеспечить некоторый механизм специальных значений.

В следующий раз мы обсудим соответствующий механизм, предлагаемый Д&Д в их Tutorial D.

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

У меня имеются сильные сомнения относительно реальности последнего суждения. В прошлом предпринимались многочисленные попытки реализации SQL с использованием реляционной алгебры, и они приводили к необходимости очень сильных расширений алгебры. При той реляционной чистоте, которую Д&Д требуют от языка D, его возможностей, скорее всего, не хватит для реализации огромного и разнородного языка SQL.



Отрицательные RM-утверждения


Отрицательные RM-утверждения

Язык D не должен содержать конструкции, зависящие от определения какой бы то ни было упорядоченности атрибутов отношений. Для каждого отношения r, выражаемого средствами D, атрибуты r должны различаться своими именами.

Язык D не должен содержать конструкции, зависящие от определения какого бы то ни было порядка кортежей отношения.

Для каждого отношения r, если t1 и t2 являются разными кортежами этого отношения, должен существовать такой атрибут A отношения, что сравнение "A FROM t1 = A FROM t2" принимает значение false (выражения A FROM t1 и A FROM t2 означают значения атрибута A в кортежах t1 и t2 соответственно).

Каждый атрибут каждого кортежа должен иметь значение (соответствующего типа).

Это один из первых намеков Д&Д на то, что не должны поддерживаться неопределенные значения (NULL). С моей точки зрения, при всех отрицательных явлениях, порождаемых неопределенными значениями, пока Д&Д не удалось предложить альтернативный работающий подход.

В языке D должно учитываться, что отношения без атрибутов приемлемы и интересны и что то же относится к возможным ключам без компонентов.

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

Не должно быть покортежных операций на relvar или отношениями.

В языке D не должны поддерживаться "составные домены" или "составные атрибуты", поскольку подобной функциональности можно достичь, если это желательно, на основе описанной выше поддержки типов.

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

Язык D не должен называться SQL.



Положительные OO-утверждения


Положительные OO-утверждения

Этот раздел явно подчеркивает трактовку Д&Д OO как "Other Orthogonal", а не как "Object-Oriented". По сути дела, ни одно из положительных OO-утверждений не имеет прямого отношения к объектной ориентации.

В языке D должна допускать проверка типов во время компиляции.

Если в языке D допускается определение некоторого типа T' как подтипа некоторого супертипа T, то такая возможность должна соответствовать некоторой четко определенной и общепризнанной модели.

Если в языке D допускается определение типа T' как подтипа некоторого другого типа T, то это не противоречит тому, чтобы T' определялся как подтип и некоторого иного типа, который не является типом T или каким-либо супертипом T (если требования OO-утверждения 2 не запрещают такую возможность).

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

Инициация транзакций должны производиться только средствами явного выполнения операции "begin transaction". Завершение транзакции должно производиться только средствами выполнения операций "commit" или "rollback"; фиксация всегда должна быть явной, а откат может быть неявным (если транзакция завершается неуспешно не по своей вине). Если транзакция TX завершается выполнением операции commit ("нормальное завершение"), то изменения, произведенные TX в соответствующей базе данных, должны быть зафиксированы. Если транзакция TX завершается выполнением операции rollback ("ненормальное завершение"), то изменения, произведенные транзакцией TX в соответствующей базе данных, должны быть аннулированы.

В языке D должны поддерживаться вложенные транзакции, т.е. должно допускаться образование транзакцией-предком TX транзакции-потомка TX' до завершения транзакции TX.
При этом:

TX и TX' должны взаимодействовать с одной и той же базой данных (что в действительности требуется RM-требованием 17).

Не требуется задержка выполнения TX на время выполнения TX' (хотя это и допускается). Однако TX не должна завершаться до завершения TX'; другими словами, TX' должна полностью содержаться в TX.

Откат TX должен включать откат TX', даже если TX' завершилась фиксацией. Другими словами, "фиксация" всегда интерпретируется в контексте предка (если он существует) и может быть отменена транзакцией-предком.

Пусть AggOp - агрегатная операция, такая как SUM. Если аргумент AggOp является пустым, то:

Если AggOp является сокращенной формой некоторой итеративной бинарной операции Op (в случае SUM это операция "+") и если для Op существует начальное значение (0 в случае SUM), то результатом вызова AggOp должно быть это начальное значение;

В противном случае результат вызова AggOp должен быть неопределенным.

Последнее OO-утверждение снова явно направлено на избавление от неопределенных значений. Но, во-первых, лично для меня совершенно неочевидно, что при сложении пустого набора чисел должно получиться значение 0. По-моему, это как минимум неясно с позиций интуиции. Во-вторых, во второй части этого утверждения появляется словосочетание "неопределенный результат", но что это значит, формально не поясняется.



Положительные RM-утверждения


Третий манифест

Положительные RM-утверждения

Скалярный тип данных (домен) - это именованное множество скалярных значений. Скалярные типы T1 и T2 одинаковы в том и только в том случае, когда являются одним и тем же типом. Пользователи языка D должны иметь возможность определения собственных скалярных типов; другие скалярные типы должны обеспечиваться системой. Должна иметься возможность отмены определения пользовательских скалярных типов. Значениями скалярных типов и соответствующими переменными можно оперировать только с помощью операций, определенных для этого типа. Для каждого скалярного типа и каждого объявленного возможного представления его значений в состав этих операций должны входить:

операция selector, служащая для выборки произвольного значения этого скалярного типа (см. RM-утверждение 4);

набор операций для раскрытия возможного представления (см. RM-утверждение 5).

В состав системных скалярных типов должен входить тип truth value (с двуми значениями true и false). Для этого типа должны поддерживаться все требуемые логические операции.

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

Пользователи языка D должны иметь возможность определения собственных скалярных операций; другие скалярные операции должны обеспечиваться системой. Должна иметься возможность отмены определения пользовательских скалярных операций (с оговорками RM-утверждения 5):

Определение скалярной операции должно включать спецификацию типа каждого параметра - объявленный тип параметра. Если операция Op имеет параметр P объявленного типа T, то аргумент A, соответствующий P, в каждом вызове Op должен иметь тот же тип T;

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

Скалярные операции только чтения возвращают результат, операции обновления - нет.

В определении скалярной операции только чтения должна содержаться спецификация типа результата (объявленного типа);

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

Результат вычисления скалярного выражения SX имеет объявленный тип, рекурсивно порождаемый из объявленных типов операндов SX и объявленных типов результатов подвыражений, содержащихся в SX.

Если T - это скалярный тип, а v - появление (в некотором контексте) значения этого типа, то по определению у v имеется в точности одно реальное представление и одно или более возможных представлений. Реальное представление, связанное с типом T, должно определяться средствами некоторого языка определения структуры хранения и не должно быть видимо в языке D (см. RM-утверждение 6). То же касается возможных представлений. Для каждого объявленного возможного представления PR типа T должна автоматически определяться операция selector S со следующими свойствами:

Если представить, что компоненты PR (см. RM-утверждение 5) и параметры S представлены в виде упорядоченных списков, то эти два списка должны содержать одно и то же число элементов n, и объявленные типы i-тых элементов списков (i = 1, 2, …, n) должны быть одинаковы.

Каждое значение типа T должно производиться путем некоторого вызова S.

Каждый (успешный) вызов S должен производить некоторое значение типа T.

Если некоторое объявленное возможное представление PR для скалярного типа T определено в терминах компонентов C1, C2, …, Cn (у каждого компонента имеются имя и объявленный тип), v - значение типа T, а PR(v) - его возможное представление, то PV(v) должно демонстрироваться, т.е.


автоматически должен быть определен набор операций только чтения и обновления такой, что:

Для всех значений v и для всех i (i = 1, 2, …, n) можно "выбрать" (прочитать значение) компонента Ci PR(v).

Для любой переменной V типа T и для всех i (i = 1, 2, …, n) можно обновить V таким образом, что если значениями V до и после обновления являются v и v' соответственно, то возможные представления PR(v) и PR(v') отличаются самое большее в их компонентах Ci.

Такой набор операций должен обеспечиваться для каждого возможного представления, объявленного в определении T.

Должен поддерживаться генератор типов TUPLE, т.е. при наличии некоторого заголовка кортежа H (см. RM-утверждение 9) должно быть возможно использовать генерируемый тип TUPLE {H} как основу определения (или, в случае значений, выбора):

Значений и переменных этого генерируемого типа (см. RM-утверждения 9 и 12).

Значений атрибутов кортежей и атрибутов заголовка кортежей этого генерируемого типа (RM-утверждение 9);

Компонентов объявленных возможных представлений этого генерируемого типа (RM-утверждение 5).

Генерируемый тип TUPLE {H} называется типом кортежей, и имя этого типа - TUPLE {H}. К этому типу, его значениям и переменным применима терминология степени, атрибутов и заголовков (RM-утверждение 12), вводимая в RM-утверждении 9. Типы кортежей TUPLE {H1} и TUPLE {H2} совпадают в том и только в том случае, когда H1 = H2. Применимые операции должны включать аналоги операций реляционной алгебры RENAME, project, EXTEND и JOIN (RM-утверждение 18), а также операции присваивания кортежей (RM-утверждение 21) и сравнения кортежей (RM-утверждение 22); кроме того, должна иметься (a) операция выбора кортежей (RM-утверждение 9), (b) операция извлечения из указанного кортежа значения указанного атрибута (этот кортеж должен иметь степень один - см. RM-утверждение 9) и (c) операции "nesting" и "unnesting" для кортежей.

Должен поддерживаться генератор типов RELATION, т.е. при наличии некоторого заголовка отношения H (см.


RM- утверждение 10) должна иметься возможность использования генерируемого типа RELATION {H} для определения (или, в случае значений, для выбора):

Значений и переменных этого генерируемого типа (RM-утверждения 10 и 13).

Значений атрибутов кортежей и атрибутов заголовка кортежей этого генерируемого типа (RM-утверждение 9).

Компонентов объявленных возможных представлений этого генерируемого типа (RM-утверждение 5).

Генерируемый тип RELATION {H} называется типом отношения, и имя этого типа - TUPLE {H}. К этому типу, его значениям и переменным применима терминология степени, атрибутов и заголовков (RM-утверждение 13), вводимая в RM-утверждении 10. Типы отношения RELATION {H1} и RELATION {H2} совпадают в том и только в том случае, когда H1 = H2. Применимые операции должны включать операции реляционной алгебры (RM-утверждение 18), а также операции реляционного присваивания (RM-утверждение 21) и реляционного сравнения (RM-утверждение 22); кроме того, должна иметься (a) операция выбора отношения (RM-утверждение 10), (b) операция извлечения из указанного отношения указанного кортежа (это отношение должно иметь мощность один - см. RM-утверждение 10) и (c) операции "nesting" и "unnesting" для отношений..

Для каждого типа должна быть определена операция сравнения по равенству. Если выражения X1 и X2 вырабатывают значения одного и того же типа T v1 и v2 соответственно, то операция X1 = X2 вырабатывает значение true в том и только в том случае, если v1 и v2 в действительности являются одним элементом T. Если Op - это операция с параметром P типа T, то для всех таких операций при условии, что X1 = X2, то эффект двух успешных вызовов Op, в одном из которых аргументом, соответствующим P, является X1, а в другом - X2, должен быть одним и тем же. Наоборот, если эффект двух таких вызовов Op различается, то значением сравнения X1 = X2 должно быть false.

Значение кортежа t (или для краткости кортеж) - это множество упорядоченных триплетов <A, T, v>, где:



A - имя атрибута кортежа t. Никакие два различных триплета t не должны содержать одно и то же имя атрибута.

T - имя типа атрибута кортежа t.

v - значение типа T, называемое значением атрибута A кортежа t.

Мощность множества триплетов в t, или число атрибутов t называется степенью t. Множество упорядоченных пар <A, T>, получающихся путем удаления компонента v из каждого триплета, является заголовком t. Кортеж t называется соответствующим этому заголовку (принадлежит к соответствующему типу кортежа - см. RM-утверждение 6). Степень заголовка - это степень кортежа, а атрибуты и соответствующие типы заголовка - это атрибуты и соответствующие типы кортежа t. При заданном заголовке H должна быть доступна операция selector для выбора произвольного кортежа, соответствующего H.

Значение отношения r (для краткости - отношение) состоит из заголовка и тела, где:

Заголовком r является заголовок кортежа H (RM-утверждение 9). Отношение r назызвается соответствующим этому заголовку (принадлежит к соответствующему типу отношения - RM-утверждение 7), а степенью r является степень этого заголовка. Атрибуты и соответствующие типы r - это атрибуты и соответствующие типы H.

Тело r - это множество B кортежей, каждый из которых имеет заголовок H; мощность тела называется мощностью r.

При заданном заголовке отношения H должна быть доступна операция selector для выбора произвольного отношения, соответствующего H.

Скалярная переменная типа T - это переменная, допустимыми значениями которой являются скаляры указанного скалярного типа T, объявленного типа этой переменной. В языке D должны иметься доступные для пользователей средства определения скалярных переменных. При определении скалярной переменной должна производиться инициализация переменной некоторым значением - явно указанным в операции определения переменной или не указываемым явно, определенным в реализации.

Переменная кортежа типа TUPLE {H} - это переменная, допустимыми значениями которой являются кортежи, соответствующие указанному заголовку кортежа H.


Объявленный тип этой переменной кортежа есть TUPLE {H}. Атрибутами переменной кортежа являются атрибуты H, соответствующие типы - объявленные типы этих атрибутов, степень переменной кортежа - степень H. В языке D должны иметься доступные для пользователей средства определения переменных кортежей. При определении переменной кортежа должна производиться инициализация переменной некоторым значением - явно указанным в операции определения переменной или не указываемым явно, определенным в реализации.

Переменная отношения (для краткости - relvar) типа RELATION {H} - это переменная, допустимыми значениями которой являются отношения, соответствующие указанному заголовку отношения H. Объявленный тип этой relvar есть RELATION {H}. Атрибутами relvar являются атрибуты H, соответствующие типы - объявленные типы этих атрибутов, степень relvar - степень H. В языке D должны иметься доступные для пользователей средства определения и уничтожения relvars базы данных (для тех relvar, которые принадлежат базе данных, а не приложению - см. RM-утверждение 16). Должны также поддерживаться возможности определять relvar на уровне приложений.

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

По определению у каждой relvar имеется по меньшей мере один возможный ключ. По меньшей мере один такой ключ должен быть определен при определении relvar, и не должно быть возможно ликвидировать все возможные ключи данной relvar (кроме как ликвидировав саму relvar).

База данных - это именованный контейнер relvars; содержимой базы данных в любой момент времени - это набор relvars базы данных. Требуемые операции для определения и ликвидации баз данных не должны являться частью языка D.



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

В языке D должны поддерживаться обычные операции реляционной алгебры (или их некоторые логические эквиваленты). Конкретно, должны прямо или косвенно поддерживаться по меньшей мере операции RENAME, restrict (WHERE), project, EXTEND, JOIN, UNION, INTERSECT, MINUS, (обобщенная) DIVIDEBY PER и (обобщенная) SUMMIRIZE PER. Все такие операции должны выражаться без чрезмерного многословия. В языке D должен также поддерживаться механизм наследования типов отношения, благодаря чему заголовок результата вычисления реляционного выражения должен быть правильно определенным и известным как системе, так и пользователю (см. RM-утверждение 7).

Имена relvar и вызовы селектора отношений должны быть допустимыми реляционными выражениями. В реляционных выражениях должна допускаться рекурсия.

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

В языке D должно допускаться:

Присваивание (значения) скалярного выражения скалярной переменной;

Присваивание (значения) кортежного выражения переменной кортежа;

Присваивание (значения) выражения над отношениями relvar.



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

В языке D должны поддерживаться некоторые операции сравнения, а именно:

Операции сравнения скаляров должны включать "=" и, возможно, "<", ">" и т.д. (в зависимости от данного скалярного типа);

Операции сравнения кортежей должны включать "=" и "" (и только);

Операции сравнения отношений должны включать "=", "", "является подмножеством" и т.д.;

Должна поддерживаться операция "" для проверки вхождения кортежа в отношение.

Во всех случаях, кроме "", операнды должны быть одного типа, а в случае "" кортеж и отношение должны иметь одинаковые заголовки.

Выражение, при вычислении которого вырабатывается истинностное значение, называется логическим выражением (также называемым истинностным, условным или булевским выражением). Ограничением целостности является логическое выражение, которое a) именованное; b) является замкнутой WFF (Well Formed Formula - правильно построенной формулой) или ее логическим эквивалентом реляционного исчисления; с) при вычислении дает значение true. В языке D должны обеспечиваться средства для определения и уничтожения ограничений целостности. Такие ограничения классифицируются на ограничения домена (т.е. типа), атрибута, relvar и базы данных, и в языке D должен поддерживаться механизм наследования ограничений (насколько это возможно).

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

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

Язык D должен конструироваться в соответствии с установившимися принципами правильной разработки языка.

|



>REMOVE<, >RENAME< и >COMPOSE<


>REMOVE<, >RENAME< и >COMPOSE<

>REMOTE<

Операция >REMOTE< является двойником в алгебре A квантора существования логики предикатов. Она соответствует операции project Кодда. Отличие состоит в том, что в >REMOTE< указываются не атрибуты, которые должны сохраниться в результате, а атрибуты, которые следует удалить. Мотивация Д&Д является психологической: проекция отношения с атрибутами X и Y на X эквивалентна квантификации существования по Y. Например, проекция WORKS_IN на E эквивалентна предикату на естественном языке "Существует некоторый отдел D такой, что служащий E работает в отделе D".

>RENAME<

>RENAME< ("переименовать некоторый атрибут некоторого отношения") - это еще одна примитивная операция алгебры A. Такая операция существенна для любого конкретного синтаксиса реляционных выражений, в котором атрибуты различаются по именам.

>COMPOSE<

"Макро"-операция >COMPOSE< является комбинацией >AND< и >REMOTE<. При выполнении операции к общим атрибутам отношений, для которых выполняется >AND<, затем применяется >REMOTE<. Имя операции >COMPOSE< отражает то суждение, что такая реляционная композиция является естественным обобщением функциональной композии (композицией двух функций f (…) и g (…) -- в таком порядке -- является функция f (g (…) )). Операция реляционной композиции упоминалась в ранних статьях Кодда, но в последствии по некоторым причинам он ее устранил; Д&Д сочли эту операцию полезной для поддержки их намерения трактовать операции как отношения.



Транзитивное замыкание


Транзитивное замыкание

Алгебра A отходит от оригинальной алгебры Кодда еще в одном отношении: она включает явную операцию транзитивного замыкания >TCLOSE<. Чтобы объяснить, как работает операция, рассмотрим отношение MM (рис. 1). Это отношение является примером того, что иногда называют диграфовым отношением, поскольку его можно представить как направленный граф.

MM MAJOR_P# : P# MINOR_P# : P# ------------------------------------- P1 P2 P1 P3 P2 P3 P2 P4 P3 P5 P4 P6

Рис. 1 Отношение MM

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

Рис. 2 Граф отношения MM

Рис. 3 Граф отношения MM в виде иерархии

Поскольку MM является бинарным отношением, к нему можно применить операцию транзитивного замыкания. Операция описывается следующим образом:

Пусть r - это бинарное отношение с атрибутами X и Y одного и того же типа T. Тогда транзитивное замыкание r (>TCLOSE< r) - это отношение r+ с тем же заголовком, что у r, и телом, являющимся надмножеством тела r, определяемым следующим образом: Кортеж

{ < X, T, x >, <Y, Y, y> }

входит в r+ том и только в том случае, когда он входит в r или существует последовательность значений z1, z2, …, zn (все типа T) таких, что кортежи

{ < X, T, x >, < Y, T, z1 > }

{ < X, T, z1 >, < Y, T, z2 > }

         ……………………

{ < X, T, zn >, < Y, T, y > }

все входят в r. Другими словами кортеж "(x, y)" входит в результат, только если существует путь в графе из узла x в узел y. Вот результат транзитивного замыкания отношения MM (рис. 4).

MAJOR_P# : P# MINOR_P# : P# ----------------------------- P1 P2 P1 P3 P2 P3 P2 P4 P3 P5 P4 P6 P1 P4 P1 P5 P1 P6 P2 P5 P2 P6

Рис. 4 Транзитивное замыкание MM

|



Третий манифест Кристофера Дейта и Хью Дарвена: предпосылки и обзор


1999 г

Третий манифест Кристофера Дейта и Хью Дарвена: предпосылки и обзор

Летом 1998 г. в издательстве Addison-Wesley вышла книга Криса Дейта и Хью Дарвена "Foundation for Object/Relational Databases: The Third Manifesto". В этой книге глубоко и обоснованно развиваются идеи, первоначально сформулированные в статье тех же авторов [1]. На мой взгляд, книга содержит ряд спорных утверждений и предположений, но прошедшие со дня ее выхода месяцы показали наличие достаточно активного интереса к книге, и имеются основания полагать, что она повлияет на будущие теорию и практику баз данных.

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

Первая статья посвящается вводной главе книги "Предпосылки и обзор", в которой описываются причины, побудившие авторов к ее написанию, и приводится краткий обзор базовых идей, а также второй главе "Объекты и отношения", где обсуждаются связь понятий "объект" и "отношение".

Предпосылки и обзор

Причины написания книги

Указываемой первичной причиной является неудовлетворенность предлагаемыми другими исследователями и авторами подходами к интеграции реляционной и объектной технологии. Публикации [1] предшествовали два манифеста - Манифест объектно-ориентированных систем баз данных [2] и Манифест систем баз данных третьего поколения [3], в каждом из которых предлагался некоторый базис для развития будущих СУБД. Но при этом:

В [2], по существу, игнорируется реляционная модель. По мнению Дейта и Дарвена (далее Д&Д) уже только этого больше, чем достаточно, чтобы вывести объектные системы из числа конкурентов реляционных систем.

Это первое спорное утверждение. Как известно, объектно-ориентированные и другие нереляционные СУБД достаточно успешно существуют и используются.


1999 г

Третий манифест Кристофера Дейта и Хью Дарвена: немного формализма

Продолжаю знакомить вас с книгой Криса Дейта и Хью Дарвена "Foundation for Object/Relational Databases: The Third Manifesto". В этой статье мы рассмотрим третью и четвертую главы книги - "Третий манифест" и "Новая реляционная алгебра". Третья глава читается не очень легко. Она написана в очень формальном стиле и не содержит пояснений. Но без этого материала трудно понять следующие, неформальные и дискуссионные главы. Мне очень нравится четвертая глава, где вводится новая, минимизированная версия реляционной алгебры. По-моему, создание этой алгебры относится к высшим достижениям авторов книги. По причине формального характера этих глав в предлагаемом вашему вниманию сокращенном пересказе содержится не слишком много моих собственных комментариев. В обзоре главы про алгебру их нет вообще, поскольку у меня действительно отсутствуют какие-либо замечания по поводу этого материала.




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

В отличие от этого, Д&Д категорически утверждают, что в интересах будущего развития требуется полностью отказаться от SQL. Осознавая наличие громадного числа SQL-ориентированных баз данных и приложений, которые будут продолжать использоваться в течение долгого времени, Д&Д соглашаются с тем, что требуется уделять некоторое внимание продолжению поддержки наследства SQL.

Назад к реляционному будущему

Основным тезисом книги является то, что мы должны отказаться от SQL и вернуться к реляционным истокам. Д&Д считают, что необходимую основу обеспечивает Реляционная Модель Данных, впервые представленная миру Эдвардом Коддом в 1969 г. Признавая желательность объектно-ориентированных свойств в системах баз данных, Д&Д полагают, что эти свойства являются ортогональными к реляционной модели. Не требуются какие-либо переделки реляционной модели, чтобы можно было определить язык, который

Был бы истинно реляционным (в отличие от SQL) Включал бы такие ортогональные свойства Мог бы служит искомой основой.

Если предположить существование такого языка D (а позже в книге приводится неформальное описание языка Tutorial D), то, по мнению Д&Д, он должен соответствовать ряду положительных и отрицательных утверждений (prescriptions и proscriptions). Авторы выделяют утверждения, происходящие из реляционной модели (RM Prescriptions), и те, которые к ней не относятся, - Other Orthogonal (OO) Prescriptions.

Обратите внимание, что везде далее в книге OO используется именно в смысле Other Orthogonal, а не Object-Oriented, хотя, конечно, в основном имеются в виду объектные свойства.

При этом утверждения категории RM считаются необсуждаемыми, но что касается OO-утверждений, то отсутствие общепризнанной модели делает их в некотором роде "пробными".


Кроме того, в книге содержится набор Весьма Строгих Утверждений, которые тоже разбиты на категории RM и OO.

Некоторые руководящие принципы

Во всей своей книге Д&Д следуют некоторым руководящим принципам, среди которых основным и определяющим является максима, принадлежащая, как думают авторы, Людвигу Витгенштейну:

ВСЕ ЛОГИЧЕСКИЕ РАЗЛИЧИЯ ЯВЛЯЮТСЯ БОЛЬШИМИ РАЗЛИЧИЯМИ

Это особенно важно к контексте реляционной модели, являющейся формальной системой, а основой любой формальной системы является логика.

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

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

Наконец, еще один фундаментальный принцип, которому очень трудно следовать, почерпнут из Мифического человекомесяца Фреда Брукса - это принцип концептуальной целостности.

Некоторые решающие логические различия

Модель и реализация

Модель - это абстрактное, замкнутое, логическое определение объектов, операций и т.д., представляющее абстрактную машину, с которой взаимодействуют пользователи.

Реализация данной модели - это физическая реализация компонентов модели на реальной компьютерной системе.

В книге главным образом обсуждаются аспекты модели, а не реализации. Кроме того, под реализацией понимается реализация "системы" (т.е. СУБД), а не некоторого приложения, работающего под управлением этой системы.

Думаю, что с таким определением модели не согласятся математики, хотя на интуитивном уровне оно правильно. Вообще говоря, поскольку модель - это формальная система, ее определение тоже должно быть формальным.

Значения и переменные

Люди часто путают эти простые и фундаментальные понятия.


В соответствии с Кливлэндом в книге используются следующие определения:

Значение - это индивидуальная константа (например, константа "3"). У значения нет своего места во времени и пространстве. Однако значения могут быть представлены в памяти посредством некоторой кодировки и, конечно, у таких кодировок имеется место во времени и пространстве. По определению, значение невозможно модифицировать.

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

Значения могут быть произвольно сложными; например, значение может быть массивом, стеком, списком, геометрической точкой, документом и т.д. Аналогичные замечания относятся и к переменным.

Как отмечают Д&Д, большая путаница по поводу значений и переменных имеется в объектном мире, где различают тип переменной и тип объекта, являющегося текущим значением этой переменной; объекты и значения; признают наличие операций, воздействующих на состояние объекта. Именно по причине этой путаницы авторы книги стараются вообще не использовать термин "объект".

Значения, кодировки и появления

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



Умышленно опущенные темы

Имеется много практически необходимых аспектов систем управления данными, которые не имеют отношения к логической основе таких систем. К этим аспектам, в частности, относится следующее:

Восстановление и многопользовательский доступ к данным Безопасность и авторизация Хранимые процедуры и триггеры Поддержка разработки приложений общего вида (иногда это называют call-level интерфейс) Вопросы масштабирования и эфективности.

Книга не ориентирована на обсуждение подобных аспектов.

Сводка утверждений и очень строгих суждений

Положительные RM-утверждения

Скалярные типы Скалярные значения типизированы Скалярные операции Реальные и возможные представления Раскрытие возможных представлений Генератор типа TUPLE Генератор типа RELATION Равенство Кортежи Отношения Скалярные переменные Кортежные переменные Переменные отношений (relvars) Реальные и виртуальные relvars Возможные ключи Базы данных Транзакции Реляционная алгебра Имена relvars, селекторы отношений и рекурсия Операции над значениями отношений Присваивания Сравнения Ограничения целостности Предикаты над relvar и базами данных Каталог Разработка языка

Отрицательные RM-утверждения

Отсутствие упорядоченности атрибутов Отсутствие упорядоченности кортежей Отсутствие кортежей-дубликатов Отсутствие неопределенных значений Отсутствие ошибок логики неопределенных значений Отсутствие конструкций внутреннего Уровня Отсутствие операций уровня кортежей Отсутствие составных атрибутов Отсутствие возможности преодоления проверок доменов Не SQL

Положительные OO-утверждения

Проверка типов во время компиляции Простое наследование (условно) Множественное наследование (условно) Вычислительная полнота Явные границы транзакций Вложенные транзакции Агрегаты и пустые множества

Отрицательные OO-утверждения

Relvars - это не домены Отсутствие идентификаторов атрибутов

Очень строгие RM-суждения

Системные ключи Внешние ключи Вывод возможных ключей Ограничения переходов Запросы с квотами Обобщенное транзитивное замыкание Параметры кортежей и отношений Специальные значения (по умолчанию) Миграция от SQL



Очень строгие OO-суждения

Наследование типов Типы и операции не связаны Генераторы типов коллекций Преобразование в отношения и из отношений Одноуровневое хранение

Объекты и отношения



Введение

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

Можно предложить два возможных ответа на поставленный вопрос:

домен = объектный класс отношение = объектный класс.

В главе показывается, что первый ответ - правильный, а второй - нет.

Что за проблему мы пытаемся решить?

Исходным положением является то, что для будущих баз данных потребуются гораздо более сложные виды данных, чем те, которые поддерживаются в современных коммерческих базах данных. Возникает потребность хранить графические данные, аудио- и видеоданные и т.д. Каким образом можно поддерживать новые виды данных, оставаясь в классической реляционной среде? Д&Д принимают как аксиому то, что мы хотим остаться в классической реляционной среде; было бы неразумно забыть о результатах многолетних исследований и разработок в этой области.

Отношения и relvars

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

MMQMAJOR_P# : P#MINOR_P# : P#QTY : QTY
 P1P25
 P1P33
 P2P32
 P2P47
 P3P54
 P4P68
Рис. 1. Отношение инвентарной ведомости MMQ

Как видно, каждое отношение состоит из двух частей - заголовка и тела, где заголовок - это множество пар имя-столбца:имя-домена, а тело - множество строк, соответствующих этому заголовку. Для отношения MMQ:

MAJOR_P#, MINOR_P#, QTY - имена столбцов; P#, P#, QTY - имена соответствующих доменов; Каждая строка включает значения MAJOR_P# (из домена P#), MINOR_P# (из домена P#) и QTY (из домена QTY).



Замечание Д&Д: Из соображений точности изложения в книге используется термин "отношение", а не термин "таблица", и термины "атрибут" и "кортеж", а не "столбец" и "строка". Исключения из этого правила допускаются только в тех случаях, где точность необязательна.

Как видно из дальнейшего изложения эти исключения встречаются чрезвычайно часто.

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

part MAJOR_P# contains QTY of part MINOR_P#

(деталь MAJOR_P# содержит QTY деталей MINOR_P#)

Соответствующими истинными высказываниями являются следующие:

part P1 contains 5 of part P2

(деталь P1 содержит 5 деталей P2);

part P1 contains 3 of part P3

(деталь P1 содержит 3 детали P3) и т.д.

Коротко говоря,

домены содержат то, о чем мы говорим; отношения содержат истинные факты о том, о чем мы говорим.

Поэтому

необходимы и домены, и отношения (без доменов нам не о чем говорить, без отношений мы не сможем ничего сказать); домены и отношения - это не одно и то же.

Хорошей, хотя и не вполне строгой аналогией является то, что домены для отношений - то же самое, что существительные для предложений.

Вернемся теперь к исторически существующей путанице между значениями отношений и переменными отношений. Если мы говорим на некотором языке программирования

DECLARE N INTEGER … ;

то N - это не целое число, это целая переменная, значениями которой являются целые числа. Точно так же, когда мы говорим на языке SQL

CREATE TABLE R … ;

то R - это не отношение, а переменная отношения, значениями которой являются отношения. Когда мы обновляем R (например, вставляем строку), то на самом деле заменяем старое значение-отношение R на новое, другое значение-отношение.



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

Стремясь внести в эти вопросы максимальную ясность, Д&Д используют в своей книге термин relvar как сокращенную форму от relation variable (переменная отношения).

Домены и объектные классы

Многие люди слабо разбираются в том, что такое домен. Обычно они считают, что домен - это всего лишь пул значений, из которого берутся реальные значения столбцов отношений. Этого недостаточно. Домен - это то же самое, что тип данных, возможно, определенный в систем тип (такой как INTEGER или CHAR), но в более общем случае простой определенный пользователем тип (такой как P# или QTY на рис. 1). Поэтому далее Д&Д используют термины "тип" и "домен" попеременно.

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

Если система поддерживает домены должным образом, то ее пользователи должны иметь возможность определять собственные домены. И для домена P#, вероятно, были бы определены операции "=", "<" и т.д., но не операции "+", "*" и т.д., поскольку арифметические операции над номерами деталей, скорее всего, бессмысленны.



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

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

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

Следующее утверждение настолько важно, что Д&Д повторяют его в другой формулировке:

Вопрос о том, какие поддерживаются типы данных ортогонален вопросу поддержки реляционной модели.

Итак, в реляционном мире домен - это тип данных, определяемый системой или пользователем, обладающий произвольной внутренней сложностью, и значениями этого типа можно манипулировать только с помощью определенных для него операций. Объектный класс обладает точно такими же характеристиками. Другими словами, домены и объектные классы - это одно и то же. Поэтому Д&Д уверены, что при должной поддержке доменов реляционные системы смогут управлять всеми видами данных, которыми могут управлять объектные системы, но реляционные системы смогут управлять и такими видами данных, которыми не могут управлять объектные системы (временные ряды, биологические и финансовые данные и т.д.). Истинная "объектно/реляционная" система - это ни что иное, как истинная реляционная система.

Хочу заметить, что здесь c Д&Д можно поспорить. Конечно, при отсутствии общепринятой объектной модели можно считать, что класс - это то же самое, что тип данных.


Но достаточно часто либо (a) понятие класса нагружается еще и смыслом "контейнера", хранящего все существующие экземпляры (объекты) класса, либо (b) одновременно поддерживаются понятия и типа данных, и класса объекта в разных смыслах. И это только небольшая часть возражений, которые я мог бы предъявить Д&Д от имени "объектного мира".

Relvars и объектные классы

В предыдущем разделе был поставлен знак равенства между объектными классами и доменами. Однако многие считают, что объектным классам соответствуют relvars. Д&Д считают это серьезной логической ошибкой. Из чего она проистекает?

Рассмотрим следующее определение класса на гипотетическом объектном языке:

CREATE OBJECT CLASS EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) … ;

Здесь EMP#, ENAME и т.д. - это переменные экземпляра (называемые также членами или атрибутами), значения которых в каждом "экземпляре" класса EMP в любой момент времени составляют общее значение этого экземпляра в данный момент времени. В "чистой" объектной системе эти переменные экземпляра являются частными (т.е. скрытыми от пользователя), но в следующем ниже обсуждении предполагается, что они "публичные".

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

Теперь рассмотрим простое реляционное определение relvar на языке SQL:

CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) ;

Эти два определения выглядят очень похоже, наводя на мысль, что определяется одно и то же. Однако второе определение допускает ряд возможных расширений (приводимые расширения основаны на конкретном коммерческом продукте, название которого Д&Д не оглашают, но судя по общему направлению дискуссии, это Informix Universal Server).



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

CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY CHAR (20) , WORKS_FOR CHAR (20) ) ;

CREATE TABLE ACTIVITY ( NAME CHAR (20) , TEAM INTEGER ) ;

CREATE TABLE COMPANY ( NAME CHAR (20) , LOCATION CITYSTATE ) ;

CREATE TABLE CITYSTATE ( CITY CHAR (20 ) , STATE CHAR (2) ) ;

Сразу заметим, что это противоречит жесткому требованию Д&Д того, что relvar не является доменом.

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

Аналогичные замечания относятся к второму возможному расширению, в котором допускаются столбцы со значениями-отношениями, т.е. столбцы, значениями которых являются множества строк из некоторой другой (или той же самой) relvar. Например, если у каждого служащего может быть несколько хобби, то определение EMP могло бы выглядеть следующим образом:

CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) ;

Третье расширение допускает наличие методов, ассоциированных с relvars (термин "метод" является обычной для объектного мира заменой термина "операция"). Например,

CREATE TABLE EMP ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;

Программный код, релизующий метод, можно было бы написать, например, на языке Си.

Наконец, еще одно расширение допускает определение подклассов. Например, допускаются следующие определения:



CREATE TABLE PERSON ( SS# CHAR (9) , BIRTHDATE DATE , ADDRESS CHAR (50) ) ;

CREATE TABLE EMP AS SUBCLASS OF PERSON ( EMP# CHAR (5) , ENAME CHAR (20) , SAL NUMERIC , HOBBY SET OF ( ACTIVITY) , WORKS_FOR COMPANY ) METHOD RETIREMENT_BENEFITS ( ) : NUMERIC ;

Теперь EMP обладает тремя дополнительными столбцами, унаследованными от PERSON. Если бы у PERSON были методы, они были бы также унаследованы. Таблицы PERSON и EMP представляют пример того, что называется супертаблицой и подтаблицей соответственно.

Конечно, при наличии таких расширительных определений потребовались бы и манипуляционные расширения, например:

путевые выражения (например, EMP.WORKS_FOR.LOCATION.STATE), которые могут возвращать скаляры, строки или отношения, причем в двух последних случаях компонентами строк или отношений могут быть строки или отношения и т.д. литералы строк и отношений, например, ( 'E001', 'Smith', $50000, ( ( 'Soccer', 11 ) , ( 'Bridge', 4) ) , ( 'IBM', ( 'San Jose' , 'CA' ) ) ) операции реляционного сравнения, например, SUBSET (строгое подмножество) и SUBSETED операции для обхода иерархии классов возможность вызова методов в разделах, например, SELECT и WHERE (в терминах SQL) возможность доступа к индивидуальным компонентам значений столбца, если это строки или отношения.

Сколько места потребовалось для краткого обзора того, как идея "relvar = класс" воплощается на практике! И что же здесь неправильно?

Прежде всего это неправильно, поскольку relvar - это переменная, а класс - это тип. Равно как значение отношения не есть домен, так и relvar - не есть домен. Уже из этого видно, что идея проваливается. Но можно привести еще несколько соображений:

Из соотношения "relvar = класс" следует, что "строка = объект", а "столбец = (публичная) переменная экземпляра. Но истинный объектный класс обладает методами и в нем не допускаются публичные переменные экземпляра, а "объектный класс" relvar обладает публичными переменными экземпляра и только необязательно - методами. Имеется важное логическое различие между определениями столбцов (например) "SAL NUMERIC" и "WORKS_FOR COMPANY".


NUMERIC - это истинные тип данных (истинный, хотя и примитивный, домен); он накладывает независимые от времени ограничения на значения столбца SAL. COMPANY - это не истинный тип данных; ограничения, накладываемые им на значения столбца WORKS_FOR зависят от текущего значения relvar COMPANY. Здесь снова проявляется разница между relvar и доменом. "Объекты"-строки могут содержать другие "объекты". Но в действительности они содержат указатели на эти "включаемые объекты", и это должно быть абсолютно ясным пользователям. Например, если пользователь меняет некоторую строку отношения COMPANY, то это изменение будет сразу отражено во всех строках отношения EMP, которые "содержат" данную строку. Это не то чтобы плохо, но должно быть предельно ясно.

Вот еще ряд вопросов по тому же поводу:

Можно ли вставить в EMP строку с указанием значения "содержащейся" строки COMPANY, которое в это время отсутствует в relvar COMPANY. Если ответ - "да", то это значит, что определение столбца WORKS_FOR как имеющего тип COMPANY не очень осмысленно, поскольку не срабатывает должным образом ограничение операции вставки. Если же ответ - "нет", то операция вставки становится недопустимо сложной, поскольку пользователь должен не только указать название существующей компании (внешний ключ), но всю существующую строку отношения COMPANY. И конечно, придется дословно повторять уже известную системе информацию. Предположим, что мы хотим использовать для компаний правило ON DELETE RESTRICT (т.е. запретить удалять компании, в которых еще есть сотрудники). Видимо, для реализации этого правила потребуется явный процедурный код, скажем, метод M (поскольку у relvar EMP нет внешнего ключа, но невозможно использовать декларативную форму этого правила). Следовательно, операцию DELETE языка SQL для отношения EMP можно будет выполнить только внутри программного кода, реализующего метод M. Каким образом поддерживать это требование? Аналогичные замечания можно сделать по поводу других ссылочных действий, например, DELETE CASCADE. Удаление строки из EMP, видимо, не приведет к "каскадному" удалению соответствующей строки COMPANY, несмотря на то, что строка отношения EMP содержит эту строку COMPANY.



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

Предположим, что определяется представление V как проекция EMP на один столбец HOBBIES. Конечно, V - это тоже relvar, но порожденная, а не базовая. Если "relvar = класс", то и V - это класс. Но что это за класс? Кроме того, у классов имеются методы; какие методы применимы к V? У EMP есть всего один метод RETIREMENT_BENEFITS, и он, конечно, не применим к "классу" V. Похоже, что к проекции вообще не применимы никакие методы, т.е. это вообще не класс. Конечно, можно было бы сказать, что это класс с публичными переменными экземпляра и без методов, то в настоящем-то классе должно быть ровно наоборот.

На самом деле, ясно, что когда люди отождествляют relvars и классы, они имеют в виду базовые relvars и забывают про порождаемые. На проводить различие между базовыми и порождаемыми relvars - это серьезнейшая ошибка.

Заметим, что это не очень сильное замечание, поскольку, теоретически никто не мешает разрешить определять методы при определении представления. Другое дело, что SQL-92 позволяет использовать запросы в разделе FROM запроса, и тогда действительно приходится иметь дело с чисто порождаемыми relvars, для которых негде определять методы (не делать же это прямо в тексте запроса).

Наконец, какие домены поддерживаются? При отождествлении relvars и классов домены не вписываются в общую схему.

Можно подвести следующий итог этого раздела. Очевидно, что можно построить систему на основе ложной идеи "relvar = класс" и, более того, такие системы уже существуют. Но также очевидно, что эти системы напоминают автомобиль без масла или дом, построенный на песке: они могут быть даже полезны на некоторое время, но в конце концов обречены на неудачу.

Замечание по поводу наследования



В разделе "Домены и объектные классы" не упоминается возможность наследования не потому, что Д&Д не хотели этого, а вследствие отсутствия четко определенной и общепринятой модели наследования ко времени написания книги. Поэтому предполагается условная поддержка наследования в том смысле, что "если наследование поддерживается, то оно должно соответствовать некоторой правильно определенной и общепризнанной модели".

Заключительные замечания

По мнению Д&Д в объектной технологии имеется одна безусловно хорошая идея - определяемые пользователями типы (включая определяемые пользователями операции). Одна идея является вероятно хорошей - наследование типов. Ключевой идеей Д&Д является то, что эти две идеи полностью ортогональны реляционной модели. Чтобы достичь объектной функциональности, с реляционной моделью не требуется делать абсолютно ничего. Что требуется от поставщиков, это чисто реляционные СУБД (это не означает "SQL-ориентированные системы) с должной поддержкой доменов, и тогда мы получим желаемые "объектно/реляционные" системы.

Я тоже хочу сделать некоторые замечания. Мне кажется, что материал первых двух глав книги очень силен в негативном смысле. Почти со всеми отрицательными утверждениями Д&Д трудно спорить. Что же касается положительных утверждений, например, в пользу отождествления доменов и классов, то они опираются на ограниченное и нечетко выраженное понимание объектов. Фактически сначала утверждается, что класс - это то же, что и тип данных (слишком сильное для объектного мира предположение), а потом, естественно, оказывается, что домен = класс. Довольно тавтологично, не правда ли? Нет никаких объектов, есть только типизированные значения и переменные, а раз так, то нет и объектно-ориентированного подхода.

Литература

Hugh Darwen and C.J.Date. "The Third Manifesto: Foundation of Object/Relational Databases," In C.J.Date: Relational Database Writings 1994-1997. Reading, Mass.: Addison-Wesley (1998).A version of this paper also be found on the World Wide Web at . Malkolm Atkinson et al. The Object-Oriented Database System Manifesto," Proc. First International Conference on Deductive and Object-Oriented Databases, Kyoto, Japan (1989). New York, N.Y.: Elsevier Science (1990). Michael Stonebraker et al. "Third Generation Database System Manifesto", ACM SIGMOD Record 19, No. 3 (September 1990). E.F.Codd. "A Relational Model of Data for Large Shared Data Banks," CACM 13, No. 6 (June 1070). Republished in "Milestones of Research", CACM 26, No. 1 (January 1982) J. Craig Cleaveland: An Introduction to Data Types. Reading, Mass.: Addison-Wesley (1986).



Заключительные замечания


Заключительные замечания

Должно быть ясно, что алгебра A реляционно полна. В предыдущих алгебрах для этого требовалось шесть операций (обычно RENAME, restrict, project, TIMES, UNION и MINUS); Д&Д удалось сократить их число до пяти. Благодаря тому, что операции трактуются как отношения, удалось обойтись без операций EXTEND и SUMMARIZE.

Замечания:

На самом деле алгебра A "более чем" реляционно полна: неограниченные операции и >OR< и >NOT< позволяют определить отношения, которые было невозможно определить в предыдущих алгебрах. Это замечание является чисто академическим, поскольку на практике операции >OR< и >NOT< не будут полностью неограниченными, поскольку в противном смысле возникают некоторые вычислительные проблемы. В соответствии с законами Де Моргана для достижения реляционной полноты не обязательно поддерживать обе операции >AND< и >OR<. Например, A>AND<B эквивалентно >NOT<((>NOT<A)>OR<(>NOT<B), и поэтому при наличии операций >NOT< и >OR< можно было бы отказаться от >AND<. Можно было бы даже свернуть >NOT< и >OR< в одну операцию >NOR< ("neither A nor B", что эквивалентно "not A and not B"). Аналогичным образом можно было отказаться от >OR< и свернуть >AND< и >NOT< в одну операцию >NAND< ("not A or not B"). В результате при желании можно сократить алгебру A до всего лишь трех операций: >RENAME<, >REMOVE< и либо >NOR<, либо >NAND< (плюс операция >TCLOSE<, обсуждаемая в последнем разделе этой главы.

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