Главная » SQL, Базы данных » ВТОРОЕ СЕРЬЕЗНОЕ ЗАБЛУЖДЕНИЕ ЗАБЛУЖДЕНИЕ ОБЪЕКТНОГО ПОДХОДА

0

В этом разделе рассматривается второе серьезное заблуждение; как будет  видно из дальнейшего изложения, это второе заблуждение является логическим  следствием из первого, но оно также является значимым само по себе. В действительности, даже если удается избежать первого серьезного заблуждения, то можно стать жертвой второго, отдельно взятого. И следствия этого заблуждения фактически обнаруживаются почти во всех объектно-реляционных программных  продуктах, имеющихся на рынке, а также в стандарте SQL (см. раздел 26.6). Это заблуждение заключается в том, что смешиваются указатели и отношения.

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

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

■  Атрибуты со значениями в виде кортежа или в виде отношения. Безусловно, автор не возражает против таких атрибутов (и на каких основаниях он стал бы против них возражать?). В действительности, он возражает, во-первых, против той идеи, что такие атрибуты должны иметь именно те значения,  которые в настоящее время присутствуют в некоторой другой (базовой) переменной отношения, и, во-вторых, против идеи, чтобы такие атрибуты по существу имели значения, которые являются не кортежами или отношениями как таковыми, а скорее указателями на кортежи или отношения (а это означает, что на самом деле речь вообще не идет об атрибутах со значениями в виде кортежей или в виде отношений).  Примечание. На самом деле идея использования указателей, которые  ссылаются на кортежи или отношения    (а   под   этим   подразумеваются   именно   значения   кортежей   или отношений)  вообще  не  имеет  смысла;  эта  тема  обсуждается  более  подробно немного позже.

■    Связывание операторов ("методов") с переменными отношения. Автор не возражает также и против этой идеи; она практически просто определяет понятие триггеров (или хранимых процедур) в другой формулировке. Но автор фактически возражает против идеи, что такие операторы должны быть связаны с переменными отноше ния (и только переменными отношения), но не с доменами или типами. Он также возражает против идеи, что они должны быть связаны лишь с одной определенной переменной отношения (поскольку тем самым вводится понятие целевых факти ческих параметров, но в другой формулировке).

■    Подклассы и суперклассы. Против этого автор, безусловно, возражает. В той систе ме, в которой проводится знак равенства между переменными отношения и клас сами, подклассы и суперклассы становятся подтаблицами и супертаблицами, а к этим понятием автор относится чрезвычайно скептически (см. [14.13], а также раздел 26.6). Безусловно, должно обеспечиваться правильное наследование типов, как описано в главе 20.

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

■    Литералы кортежей и отношений. Эти средства являются важными, но их необхо димо обобщить до уровня селекторов кортежей и отношений [3.3].

■    Реляционные операторы сравнения. Эти средства также важны (хотя должны быть реализованы правильно).

■    Операторы для прохождения по иерархии классов. Если под иерархией классов в дей ствительности подразумевается иерархия переменных отношения, то (как отмечено в предыдущем разделе) автор имеет серьезные возражения, поскольку возникает вероятность  нарушения   реляционного  свойства   замкнутости   (см.   например [26.41]). Если бы понятие иерархия классов означало иерархию типов в том смысле, который указан в главе 20, то автор не имел бы возражений (но, к сожалению, дело обстоит иначе).

■    Вызов методов, например, в конструкциях SELECT и WHERE. Никаких возражений.

■    Доступ к отдельным компонентам в значениях атрибутов, которые оказались кор тежами или отношениями. Никаких возражений.

Итак, теперь сосредоточимся на проблеме смешивания указателей и отношений. В основе доводов автора лежит очень простая мысль. По определению, указатели указывают на переменные, а не на значения (поскольку переменные имеют адреса, а значения — нет). Поэтому, опять-таки по определению, если допускается, чтобы переменная отношения R1 имела атрибут, значениями которого являются указатели, направленные в переменную отношения R2, то эти указатели указывают на переменные кортежей, а не на значения кортежей. Но в реляционной модели не определено понятие переменной кортежа.

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

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

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

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

Многочисленные аргументированные доводы в поддержку изложенной выше позиции автора можно найти в [25.19] и [26.15]. См. также [26.12]—[26.14] и [26.17], где рассматривается связанное с этим и очень важное понятнесущественности (essentiality).

Несовместимость указателей и качественной модели наследования

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

было сосредоточиться на реальной проблеме, а не отвлекаться на ненужные подробности.) Еще раз рассмотрим типы ELLIPSE и CIRCLE. Допустим, что  PTR_TO_ELLIPSE И PTR_TO_CIRCLE — это соответствующие типы указателей;  иными словами, допустим, что значения типов PTR_TO_ELLIPSE И  PTR_TO_CIRCLE (выражаясь неформально) являются, соответственно, указателями на эллипсы и указателями на окружности. Наконец, допустим, что  ELLIPSE — строгий супертип типа CIRCLE и поэтому примем предположение,  что  PTR_TO_ELLIPSE — строгий супертип типа PTR_TO_CIRCLE. Теперь рассмотрим следующий фрагмент кода.

VAR E ELLIPSE ;

VAR XC PTR_TO_CIRCLE ;

Е := CIRCLE ( LENGTH ( 5.0 ), POINT ( 0.0, 0.0 ) ) ; XC := TREAT_DOWN_AS_PTR_TO_CIRCLE ( PTR_TO ( E ) ) ; THE_A ( E ) := LENGTH ( 6.0 ) ;

Пояснение

1.  Два объявления переменных говорят сами за себя.

2.  После первого присваивания (переменной Е) эта переменная содержит окруж ность с радиусом пять5. Обратите внимание на то, что в этом операторе присваи вания используется свойство заменяемости; следует также отметить, что теперь наиболее конкретным типом переменной Е является CIRCLE.

3.  Оператор PTR_TO, который присутствует в выражении справа от второго операто ра присваивания, представляет собой то, что обычно называется оператором адре сации: если дана переменная V, он возвращает адрес переменной V (т.е. указатель на эту переменную). Поэтому в рассматриваемом примере данный оператор воз вращает значение указателя типа PTR_TO_ELLIPSE. НО поскольку переменная, на которую указывает значение данного указателя, имеет наиболее конкретный тип CIRCLE, то значение указателя фактически имеет тип PTR_TO_CIRCLE, а не про сто тип PTR_TO_ELLIPSE. Таким образом, операция приведения к подклассу TREAT DOWN завершается успешно и поэтому во второй операции присваивания в переменную хс помещается указатель на переменную Е (иными словами, адрес этой переменной).

4.  Третья операция присваивания значения (псевдопеременной ТНЕ_А (Е)) является наиболее важной. Что происходит при ее выполнении? Скорее всего, здесь могут быть три возможности, которые описаны ниже, и все они не совсем приемлемы.

а) Возникает  ошибка  на этапе  прогона из-за  несоответствия  типов,  поскольку присваивание псевдопеременной ТНЕ_А не поддерживается  для переменных наиболее конкретного типа CIRCLE. Иными словами, не поддерживается обобщение с помощью ограничения, поэтому не поддерживается также уточнение с помощью ограничения, а это означает, что модель наследования неприемлема

5 Как и в главе 20, в данной главе предполагается, что декартово возможное представление для точек называется POINT, а не CARTESIAN.Поэтомувданномпримеревторымфактическимпараметромселектора CIRCLEявляется вызов соответствующего селектора POINT.

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

б)  Операция присваивания вроде бы завершается "успешно", но обобщение с помощью ограничения не происходит. Результатом этого становится то, что переменная Е теперь содержит "некруглую окружность" (ее наиболее конкрет ным типом все еще остается CIRCLE, но эта "окружность" имеет полуоси раз ной длины). Поэтому, опять-таки, модель наследования является неприемлемой (и не может рассматриваться как достоверная модель реальности), поскольку обобщение с помощью ограничения и уточнение с помощью ограничения не поддерживаются. Более того, не только переменная Е теперь содержит "некруг лую окружность", но и переменная хс указывает также на "некруглую окруж ность". Мало того, не могут поддерживаться ограничения типа! Ведь если бы они поддерживались, то не могли бы возникнуть "некруглые окружности". Иными словами, можно смело утверждать, что исключена возможность под держки ограничения целостности наиболее фундаментального вида: определяя тип, мы не можем указать, какие значения этого типа являются допустимыми.

Кстати, следует отметить, что эта ошибка допущена и в  спецификации

SQL: 1999! См. главу 20 и раздел 26.6.

в)  Операция присваивания завершается успешно и происходит обобщение с по мощью ограничения; это означает, что переменная Е теперь содержит "просто эллипс" и ее наиболее конкретным типом служит ELLIPSE. Но и тогда модель наследования является неприемлемой, поскольку переменная хс, объявлен ным типом которой служит PTR_TO_CIRCLE, теперь содержит значение наи более конкретного типа PTR_TO_ELLIPSE! Ид этого снова следует, что ограни чения типа не могут поддерживаться.

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

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

Анализ причин возникновения второго серьезного заблуждения

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

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

Поэтому автор может сделать единственно допустимое предположение, что  причиной, по которой идея смешивания указателей и отношений получила столь широкое распространение, является именно то, что лишь немногие понимают, почему из реляционной модели были с самого начала исключены указатели. Джон Сантаяна (John Santayana) сформулировал это так: "Те, кто не способен помнить прошлое, обречены его повторять" (обычно цитируется в форме: "Для тех, кто не знает истории, она повторяется"). По этому поводу автор выражает полное согласие с Морисом Уилксом (Maurice Wilkes), которому принадлежит приведенная ниже цитата [26.46].

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

26.2. ПРОБЛЕМЫ РЕАЛИЗАЦИИ

Одним важным следствием обеспечения правильной поддержки типов данных является то, что она позволяет независимым поставщикам (а также  поставщикам самих СУБД) создавать и поставлять отдельные пакеты типов,  которые могут эффективно встраиваться в СУБД. В качестве примеров можно  назвать пакеты, поддерживающие сложные алгоритмы обработки текста, обработки финансовых временных рядов, анализа геопространственных (картографических) данных и т.д. Такие пакеты называются по-разному:  пластинами данных— data blade (Informix), картриджами данных— data cartridge  (Oracle), реляционными расширителями  — relational extender6  (IBM),  прикладными пакетами — application package (это термин используется в  стандарте SQL/MM [26.25]) и т.д. В данном разделе остановимся на термине пакеты типов.

Но введение нового пакета типов в систему — нетривиальное мероприятие, и для предоставления такой возможности необходимо внести существенные изменения в проект и структуру самой СУБД. Для того чтобы всесторонне разобраться в этом  вопросе, рассмотрим, что произойдет, если, например, некоторый запрос включает ссылки на данные какого-то определяемого пользователем типа или вызовы какого-то определяемого пользователем оператора (или то и другое).

6 По.мнениюавтора,этоттерминявляетсяисключительнонеудачным.

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

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

■     В-третьих, компонент, который управляет физической памятью, должен иметь поддержку соответствующих более новых структур хранения (квадрадеревьев, R-деревьев и т.д.), которые упоминались при обсуждении задачи с прямоугольни ками в разделе 26.1. Может даже потребоваться, чтобы этот компонент позволял пользователям, обладающим соответствующими навыками, самостоятельно вво дить новые структуры хранения и методы доступа [26.29], [26.43].

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

Синтаксический анализ и проверка типов

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

■   Информация,  касающаяся  определяемых  пользователем  типов  и  операторов  (и возможно также встроенных типов и операторов) хранится в системном каталоге. Из этого следует, что сам каталог требует перепроектирования (или, по крайней мере, расширения); из этого также следует, что введение каждого нового пакета типов влечет за собой  существенное обновление каталога. (В терминах языка Tutorial D такое обновление незаметно для пользователя осуществляется в составе процесса  выпелнения соответствующих определительных  предложений TYPE и OPERATOR.)

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

Оптимизация

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

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

а)  Если дано такое выражение, как NOT    (STATUS   >   2 0 ) , то качественный обычный оптимизатор преобразует его в STATUS  > 20 (поскольку во второй версии можно воспользоваться индексом на столбце STATUS, а в первой — нельзя). По аналогичным причинам нужен способ, с помощью которого можно было бы сообщить оптимизатору, что один определяемый пользователем опе ратор является отрицанием другого.

б)  Качественный обычный оптимизатор имеет также информацию о том, что, на пример, выражения STATUS >  20 и 20   <   STATUS логически эквивалентны. Поэтому должен быть предусмотрен способ передачи оптимизатору информа ции о том, что два определяемых пользователем оператора являются противо положными друг другу в указанном смысле.

в)  Кроме того, качественный обычный оптимизатор имеет информацию о том, что, например, операторы "+" и "-" взаимно компенсируют друг друга (т.е. являются обратными по отношению друг к другу); например, выражение STATUS + 20 20 можно сократить просто до STATUS. Должен быть преду смотрен способ передачи оптимизатору сведений о том, что два определяемых пользователем оператора являются обратными по отношению друг к другу, в указанном смысле.

■     Избирательность. Если дано логическое выражение, такое как STATUS  >   20, то оптимизаторы обычно принимают предположение об избирательности этого вы ражения (т.е. о том, какова процентная доля кортежей, при обработке которых это выражение примет значение TRUE). В отношении встроенных типов данных и операторов эта информация об избирательности также может быть "жестко зако дирована" в оптимизаторе; в отличие от этого, применительно к определяемым пользователем типам и операторам должен быть предусмотрен способ предостав ления оптимизатору некоторого определяемого пользователем кода, который он мог бы вызвать, чтобы выработать предположение об избирательности.

■     Определение стоимости. Оптимизатор должен иметь информацию о том, сколько будет стоить выполнение конкретного определяемого пользователем оператора. Например, если дано такое выражение, как р AND q, где р — (скажем) вызов опе ратора AREA для определения площади какого-то сложного многоугольника, a q — простое сравнение наподобие STATUS  > 20, то, вероятно, следовало бы предпо честь, чтобы система вначале выполнила выражение q так, чтобы выражение р

выполнилось только на кортежах, для который q принимает значение TRUE. Безусловно, некоторые эвристические методы преобразования  выражений,  ставшие классическими (в частности, такой метод, который  всегда предусматривает выполнение операторов сокращения перед операциями соединения), не обязательно будут действительными для определяемых пользователем типов и операторов (см., например, [26.10] и [26.24]).

■   Структуры хранения и методы доступа. Оптимизатор, безусловно, должен  иметь информацию о применяемых структурах хранения и методах доступа (см. следующий подраздел).

Структуры хранения данных

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

■     Новые структуры хранения. Как уже отмечалось, для системы, по-видимому, потребуется поддержка новых "жестко закодированных" структур хранения (R-деревья и т.д.) и может даже потребоваться способ, который позволял бы поль зователям, обладающим соответствующей квалификацией, самостоятельно опре делять дополнительные структуры хранения и методы доступа.

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

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

Примечание. В главе 22 такие индексы упоминались под названием функциональных индексов.

Источник: Дейт К. Дж., Введение в системы баз данных, 8-е издание.: Пер. с англ. — М.: Издательский дом «Вильямс», 2005. — 1328 с.: ил. — Парал. тит. англ.

По теме:

  • Комментарии