- •20.7. Средства sql
- •20.8. Резюме
- •21.1. Введение
- •21.2. Некоторые аспекты технологам поддержки принятия решений
- •21.3. Проектирование базы данных поддержки принятия решений
- •21.5. Хранилища данных и магазины данных
- •21.6. Оперативная аналитическая обработка
- •21.7. Разработка данных
- •21.8. Резюме
- •22.1. Введение
- •22.2. Хронологические данные
- •22.3. Основная проблема хронологических баз данных
- •22.4. Интервалы
- •22.5. Интервальные типы
- •22.6. Скалярные операторы для интервалов
- •22.7. Операторы обобщения для интервалов
- •22.8. Реляционные операторы для обработки интервалов
- •22.9. Ограничения, включающие интервалы
- •22.10. Операторы обновления, включающие интервалы
- •22.11. Проектирование базы данных
- •22.12. Резюме
- •23.1. Введение
- •23.2. Обзор основных концепций
- •23.3. Исчисление высказываний
- •23.4. Исчисление предикатов
- •23.5. Базы данных с точки зрения доказательно-теоретического подхода
- •23.6. Дедуктивные субд
- •23.7. Обработка рекурсивных запросов
- •23.8. Резюме
- •Часть VI
- •24.1. Введение
- •24.2. Объекты, классы, методы и сообщения
- •24.3. Еще раз об объектах и объектных классах
- •Cdo для класса set (ref(emp))
- •24.4. Простой пример
- •1 | Course с001 , с001 0ffs , с001 ny offs |
- •24.5. Дополнительные аспекты
- •24.6. Резюме
- •25.1. Введение
- •X2 rational, y2 rational ) ... ;
- •25.2. Первая грубейшая ошибка
- •25.3. Вторая грубейшая ошибка
- •25.4. Вопросы реализации
- •25.5. Преимущества реального сближения двух технологий
- •25.6. Резюме
24.5. Дополнительные аспекты
В этом разделе обсуждаются некоторые традиционные аспекты управления базами данных, но в объектном контексте.
Произвольные запросы
Целостность базы данных
Реализация связей
Языки программирования баз данных
Повышение производительности
Является ли объектная СУБД действительно СУБД
Произвольные запросы
До сих пор мы преднамеренно не подчеркивали, что если для манипулирования объектами заданы только заранее определенные методы, то произвольные запросы (не предусмотренные этими методами) просто невозможны, если только классы и методы не разработаны в соответствии со специальными правилами. Например, если для объекта класса DEPT определены только методы HIRE_EMP (нанять сотрудника), FIRE_EMP (уволить сотрудника) и CUT_BUDGET (урезать бюджет), то даже такой простой запрос, как "Кто является менеджером (начальником) отдела программирования", выполнить будет невозможно.
По существу, по той же причине невозможно определить представления и декларативные ограничения целостности для объектов, опять же, если не следовать некоторым конкретным правилам.
По нашему мнению, решение этих проблем ("специальные правила") может быть следующим.
Определить множество операторов ("операторов ТНЕ_"), с помощью которых можно было бы получить некоторые возможные представления рассматриваемых объектов, как в главе 5.
Надлежащим образом внедрить объекты в реляционную структуру. Эта часть решения подробно обсуждается в следующей главе.
Однако разработчики объектных систем обычно не придерживаются данных рекомендаций. Вместо этого они поступают следующим образом10.
10 Здесь подразумевается, что рассматриваемая объектная система действительно поддерживает произвольные запросы, как и большинство современных объектных систем. Однако более ранние объектные системы иногда не поддерживали такие запросы, частично в силу причин, которые будут рассмотрены в этом разделе.
1. Обычно определяются операторы, которые предоставляют не некоторые возможные представления, а реачьные представления (см. обсуждение открытых переменных экземпляра в разделе 24.2). "В настоящее время для всех продуктов объектных СУБД требуется, чтобы [переменные экземпляра], которые упоминаются в... запросах, были открытыми" [24.38].
2. Обычно поддерживается не реляционная структура, а множество других структур, которые основываются на пакетах, массивах и т.д. В связи с этим напомним наше утверждение, что классы, т.е. типы, плюс отношения необходимы и достаточны на логическом уровне (см. главу 3). А поскольку речь идет об основной модели, мы считаем, что массивы и все остальное является ненужным и нежелательным. На наш взгляд, причиной того, что в объектных системах отдано предпочтение коллекциям, а не отношениям (фактически отношения почти полностью отвергнуты), является, опять же, путаница между понятиями модели и реализации.
В связи с выполнением произвольных запросов возникает еще один важный вопрос, а именно: какой класс является результатом. Предположим, например, что необходимо выполнить запрос "Получить имена и размер заработной платы всех служащих в отделе программирования" по базе данных отделов и служащих из раздела 24.3. Предположительно результат будет содержать открытые переменные экземпляра ENAME и SALARY. Однако в базе данных нет класса, который имеет такую структуру. Должны ли мы предварительно определить такой класс, прежде чем выполнять запрос? (Обратите внимание на последствия: если бы было необходимо определить такой класс, для класса с п переменными экземпляра потребовалось бы по крайней мере 2 п предварительно определенных класса только для поддержки операций выборки!) А если есть какой-либо класс результатов, то какие методы применимы к нему?
Аналогичные вопросы возникают в связи с операциями соединения. Если соединить объекты отдела и служащего, то какой класс получится в результате? Какие методы нужно использовать?
Возможно, из-за того, что на такие вопросы нелегко ответить, опираясь на чисто объектную структуру, в некоторых объектных системах поддерживаются операции "прохождения пути" (см, [24.25], [24.47]) вместо самих операций соединения. Для базы данных OPAL из раздела 24.4, например, допустимо следующее выражение пути.
ENROLLMENT . OFFERING . COURSE
Оно означает следующее. "Найти уникальный объект класса COURSE, на который ссылается уникальный объект класса OFFERING, на который ссылается данный объект класса ENROLLMENT"11. Реляционный аналог этого выражения обычно включает две операции соединения и одну операцию проекции. Иными словами, в результате прохождения пути предоставляется доступ только по предварительно определенным путям (как в дореляци-онных системах) и только к объектам предварительно определенных классов (опять же, как в дореляционных системах).
Целостность базы данных
'
На саман деле это выражение не
является
допустимым путем для базы данньос, как
мы ее определили, поскольку указатели
определяют неверное направление.
Например, объекты класса OFFERING
не
ссылаются на объекты класса COURSE:
наоборот,
объекты класса COURSE
ссылаются
на них.
Метод для создания объекта поставки
Метод для изменения количества поставляемых деталей
Метод для изменения статуса поставщика
Метод для переназначения некоторой поставки другому поставщику
При внимательном изучении этого примера можно отметить важные особенности.
При такой организации, очевидно, утрачивается возможность проверки соблюдения ограничений целостности с помощью системы.
Как убедиться в том, что все эти методы содержат весь необходимый для поддержки целостности базы данных код?
Как, например, при создании объектного класса для поставок предостеречь пользователя от случайного пренебрежения методом "создания поставки" и ошибочного непосредственного использования метода NEW (т.е. без проверки целостности)?
Как при изменении ограничений целостности найти и внести соответствующие изменения во все методы, в которых они были определены?
Как убедиться в корректности кода, с помощью которого приводятся в действие ограничения целостности?
Как выполнить проверку целостности для отложенных (во время выполнения) операций?
Как поступить с транзитными ограничениями?
Как узнать обо всех ограничениях, которые заданы для данного объекта или комбинации объектов?
Будут ли ограничения целостности приводиться в действие во время загрузки системы или во время выполнения каких-либо других действий?
10. Можно ли осуществить семантическую оптимизацию (т.е. упростить запросы с помощью ограничений целостности так, как описано в главе 17)?
Кроме того, как повлияют перечисленные выше особенности на производительность работы во время создания приложения и при последующем его использовании?
Реализация связей
Термин "связи" используется в объектно-ориентированных продуктах и в соответствующей литературе в основном для связей, представленных в реляционной базе данных внешними ключами. Обычно предоставляется особая поддержка для ограничений целостности специального вида. В качестве примера снова рассмотрим базу данных отделов и сотрудников. В обычной реляционной системе сотрудники имели бы внешний ключ, который ссылался бы на отделы, и этим можно было бы ограничиться. В объектных же системах, напротив, имеется по крайней мере три возможности.
Объекты сотрудников могут содержать идентификатор, который ссылается на объекты отделов. Такая возможность хотя и аналогична реляционному подходу, но не идентична ему, поскольку внешние ключи и идентификаторы — это не одно и то же.
Объекты отделов могут иметь набор идентификаторов, ссылающихся на объекты сотрудников. Эта возможность соответствует подходу, использующему иерархию вложения и описанному в разделе 24.3.
Кроме того, указанные выше подходы могут комбинироваться, как в следующих определениях.
CLASS ЕМР ...
( ... DEPT REF { DEPT ) INVERSE DEPT.EMPS ) ... CLASS DEPT ...
( ... EMPS REF
( SET ( REF ( EMP ) ) ) INVERSE EMP.DEPT ) ... ;
Отметим, что ключевое слово INVERSE относится к двум переменным: ЕМР.DEPT и DEPT.EMPS. Говорят, что эти две переменные являются обратными одна по отношению к другой. Переменная ЕМР.DEPT— это ссылочная переменная, a DEPT.EMPS — переменная набора ссылок. (Если бы обе переменные были переменными набора ссылок, то связь имела бы тип "многие ко многим", а не "один ко многим".)
Конечно, для каждой из указанных выше возможностей требуется определенного вида поддержка ссылочной целостности (см. ниже). Однако прежде всего необходимо ответить на вполне очевидный вопрос: как в объектных системах обрабатываются связи, в которых используются два и более классов, например, поставщиков, деталей и проектов. Наилучшим (т.е. наиболее симметричным) ответом на этот вопрос, конечно, будет создание объектного класса SPJ. Причем каждый объект класса будет обладать связями, реализованными с помощью "обратных переменных", с соответствующим поставщиком, соответствующей деталью и соответствующим проектом. Если создание нового объектного класса на основе трех объектов является наилучшим подходом для "связей" между двумя и более объектами, возникает вопрос, почему бы не использовать его для связей на основе двух объектов.
Кроме того, зачем нужно вводить асимметрию, задавать направленность и два разных имени для одного и того же понятия? Например, рассмотрим два следующих реляционных выражения.
SP.P# WHERE SP.Sf = St('Sl') SP.St WCodeHERE SP.Pt = Pi('PI')
Их объектные аналоги выглядят так.
S.PARTS.Pt WHERE S.Si = Sf('Sl') P.SUPPS.S* WHERE P.Pf = Pi('Pl')
(Здесь использован некий гипотетический синтаксис, выбранный специально таким образом, чтобы избежать несущественных в данном случае различий.)
Целостность на уровне ссылок
Рассмотрим уже упомянутую ранее объектную поддержку целостности на уровне ссылок, которая, кстати, как часто утверждают, является сильной стороной объектных систем. Уровни такой поддержки могут быть самыми разными; например, ниже приводится классификация таких уровней, предложенная в работе Каттелла (Cattell) [24.11].
Отсутствие системной поддержки. За поддержку целостности на уровне ссылок полностью несут ответственность пользователь и созданные им методы (как это, между прочим, и было определено в исходном варианте стандарта языка SQL).
Проверка достоверности ссылки. В системе проверяется соответствие типа данных для объекта, на который задана ссылка. Однако в этом случае может быть запрещено удаление объектов (т.е. объекты, на которые нет ссылок, могут быть "собраны вместе в мусорной куче"), как обусловлено в стандарте языка OPAL. Как уже объяснялось в разделе 24.4, этот уровень поддержки эквивалентен (но лишь весьма приблизительно) правилам каскадного удаления (ON DELETE CASCADE) в иерархии для подчиненных объектов без возможности совместного доступа и контролируемого удаления (ON DELETE RESTRICT) для других объектов (но если только "указатели ссылаются в верном направлении").
Системная поддержка. На этом уровне отслеживание и обновление ссылок происходит автоматически (например, с помощью установки значения nil для ссылок на удаленные объекты). Этот уровень в некоторой степени подобен правилу удаления ON DELETE SET NULL, используемому в реляционной системе.
"Настраиваемая семантика". Правило каскадного удаления ON DELETE CASCADE (применяемое за пределами иерархии вложения) может рассматриваться как пример "настраиваемой семантики". К моменту написания этой книги такие действия не поддерживались в объектных системах и должны были контролироваться соответствующими методами, т.е. с помощью процедур, созданных пользователем.
Языки программирования баз данных
Приведенные в предыдущей главе примеры на языке OPAL демонстрируют, что, в отличие от большинства современных реляционных программных продуктов (на основе языка SQL), в объектных системах обычно не используется "встроенный подъязык данных". Вместо этого для операций, выполняемых как с базами данных, так и с другими объектами, используется один и тот же интегрированный язык. Согласно принятой в главе 2 терминологии базовый язык и язык, ориентированный на работу с базами данных, в объектных системах тесно связаны (фактически эти два языка образуют один и тот же язык).
Такой подход, безусловно, обладает определенными преимуществами12. Одно из самых существенных— возможность осуществления усовершенствованной проверки типов [24.2]. В предлагаемой цитате из [24.47] отмечено еще одно важное достоинство.
12 В языке Tutorial D, который широко используется в данной книге, выбран такой же подход. Соображения по этому поводу изложены в [3.3].
"Благодаря простому единому языку не возникает никакого затруднения из-за несовпадения процедурного языка программирования и внутреннего языка, ориентированного на обработку данных и обладающего декларативной семантикой."
Термин затруднения из-за несовпадения используется для описания различий между типичными современными языками программирования, функционирующими на основе последовательной обработки записей, и реляционными языками наподобие SQL, функционирующими на основе последовательной обработки множеств. Очевидно, что такие различия на практике приводят к возникновению разнообразных проблем в реляционных программных продуктах. Но для их решения не нужно переводить язык, ориентированный на работу с базами данных, на уровень последовательной обработки отдельных записей (именно такое решение реализовано в объектных системах!). Необходимо в языках программирования ввести инструменты для последовательной обработки множеств записей. Применение последовательной обработки отдельных записей в объектных языках (т.е. процедурный подход) отбрасывает нас к временам, когда использовались такие дореляционные системы, как IMS и IDMS.
В отношении последнего замечания следует отметить, что в действительности большинство существующих объектных языков является либо процедурными, либо языками третьего поколения (3GL). В результате утрачиваются все преимущества реляционного подхода на основе последовательной обработки множеств. В частности, заметно уменьшается способность системы к оптимизации запросов пользователя, а значит, как и в до-реляционных системах, производительность в значительной степени определяется самим пользователем (разработчиком программы или администратором базы данных). Об этом мы поговорим более подробно в следующем подразделе.
Повышение производительности
Низкая производительность— один из самых существенных недостатков всех объектных систем. И снова процитируем, несколько перефразировав, Каттелла [24.11]: "Различие производительности на порядок реально может привести к функциональному различию, поскольку для решения некоторых задач будет невозможно использовать данную систему, если ее производительность гораздо ниже требуемого уровня".
Среди многочисленных факторов, влияющих на общую производительность системы, можно отметить следующие13.
13 Кроме перечисленных факторов, можно отметить, что в объектных системах производительность, дополнительная к той, которая существует на самом деле, достигается за счет "приближения пользователя к компьютеру", т.е. предоставления таких возможностей, как указатели, которые должны быть скрыты в реализации.
Кластеризация. Как сказано в главе 18, физическая кластеризация логически связанных данных, размещенных на жестком диске, является одним из наиболее важных факторов повышения производительности системы. В объектных системах логическая информация из определений базы данных (относительно иерархии классов, иерархии вложения или других явно заданных связей между объектами) обычно основана на макете системы и используется в качестве приблизительного плана для физической кластеризации данных. Кроме того, часто рекомендуется, чтобы администратор базы данных сам осуществлял явное и непосредственное управление отображением концептуального уровня на внутренний (по терминологии главы 2).
Кэширование. Объектные системы обычно используются в системах типа "клиент/сервер", в которых пользователи "копируют" на свои рабочие станции информацию из базы данных на сервере и хранят ее на своих рабочих станциях в течение некоторого времени. Очевидно, что в такой системе было бы полезно кэ-шировать логически связанные данные на рабочем месте клиента.
Подмена. Термин "подмена" (swizzling) означает процесс замены указателей наподобие идентификаторов объекта, в качестве которых обычно используются логические дисковые адреса, адресами оперативной памяти при считывании объектов в оперативную память (и наоборот, когда объекты записываются обратно в базу данных). Преимущества такого метода очевидны для приложений, в которых обрабатываются достаточно "сложные объекты", и поэтому необходимо часто осуществлять поиск указателей.
Выполнение методов на сервере. В качестве примера рассмотрим запрос "Найти все книги, в которых содержится более 20 глав". В традиционной реляционной системе книги могут быть представлены в виде объектов BLOB14, которые, по сути, являются строкой байтов произвольной длины. При такой организации системы клиент вынужден извлекать каждую книгу и проверять, не содержит ли она более 20 глав. Однако при наличии должной объектной поддержки на сервере может быть выполнен некоторый специализированный метод "число глав", а затем клиенту будут переданы все требуемые книги15.
Замечание. Приведенные выше преимущества на самом деле являются аргументом не в пользу объектных систем, а в пользу хранимых процедур (см. главы 8 и 21). Традиционная реляционная система с хранимыми процедурами будет обладать в этом случае таким же быстродействием, как и объектная система с методами.
В [24.13] обсуждается тестовая программа 001 для измерения производительности системы на основе базы данных, содержащей информацию о счетах и материалах. Эта программа выполняет следующие операции.
Случайное извлечение 1 ООО деталей с применением заданного пользователем метода для каждой детали..
Случайная вставка 1 ООО деталей с присоединением каждой к трем другим.
Случайное разузлование деталей (до семи уровней) с применением заданного пользователем метода для каждой детали, подсчитывающего соответствующие вхождения в узлы.
14 Замечание
относительно объектов BLOB,
Хотя
такой тип данных не включен в
стандарт
SQL/92,
SQL-продукты
традиционно предоставляют возможности
обработки данных типа
BLOB
в
качестве основы для работы с "большими
двоичными объектами " (binary
large object).
Здесь
объект понимается в общепринятом
смысле, а не в том, который вкладывается
в это по-
нятие в объектных системах.
Данные типа BLOB
представляют
собой по существу просто ка-
кую-то
строку байтов произвольной длины, для
которой в системе предоставляется
поддержка
с целью организации ее
хранения и извлечения; этим вся поддержка
и ограничивается. Физически
такие
данные часто хранятся в специально
отведенной для них области, отдельно
от основной
области хранения данных
тех отношений, которые логически
содержат эти данные. Данные
типа BLOB
могут
занимать (и часто занимают) огромные
области дискового пространства.
15 На
самом деле это сверхупрощение: методы,
которые поддерживают интенсивный
обмен
данными, лучше выполняются на
сервере; однако другие методы, т.е. те,
которые преимущест-
венно отображают
данные, может быть, лучше выполнять на
компьютере клиента.
"Это отличие... не следует приписывать различию между собственно реляционной и объектными моделями... В основном, эти различия обусловлены [особенностями реализации]."
Это утверждение может быть подкреплено тем фактом, что различия в производительности становились заметно меньше при увеличении размера базы данных (когда в кэш нельзя было поместить всю базу данных).
Подобная, но более обширная, тестовая программа 007 описана в [24.10].
Является ли объектная СУБД действительно СУБД?
Замечание. В данном подразделе излагаются суждения и наблюдения, которые, в основном, взяты из [24.18]. В этой работе, помимо всего прочего, утверждается, что различия между объектными и реляционными системами гораздо существеннее, чем это обычно представляется.
"Объектные базы данных возникли благодаря желанию отдельных программистов объектных приложений (продиктованному самыми разными причинами) хранить созданные ими специализированные объекты в постоянной памяти. При этом под такой "постоянной памятью"могла подразумеваться и база данных, но, что особо следует подчеркнуть, база данных, предназначенная для специальных приложений; она не была разделяемой и не являлась базой данных общего назначения, предназначенной для приложений, особенности которых во время определения базы данных еще нельзя предвидеть в полном объеме. Потому многие возможности, которые профессионалами по базам данных расцениваются как существенные, просто не считались необходимыми в объектном мире, по крайней мере изначально. "
На первых порах создания объектных баз данных не было достаточного понимания необходимости в том, чтобы базы данных предоставляли следующие возможности.
Совместный доступ со стороны нескольких приложений.
Физическая независимость данных.
Возможность выполнения произвольных запросов.
Поддержка представлений и логической независимости данных.
Поддержка декларативных ограничений целостности, независимых от приложений.
Поддержка прав владения данными и гибкий механизм обеспечения их защиты.
Управление совместным доступом.
Каталог общего назначения.
Возможность проектирования базы данных независимо от приложений.
"Впоследствии, после представления основной идеи хранения объектов в базе данных, эти возможности были рассмотрены и реализованы как усовершенствования и дополнения к исходной объектной модели... Один из важных выводов... заключается в том, что объектная СУБД и реляционная СУБД— системы, которые различны по сути. На самом деле можно было бы доказать, что объектная СУБД фактически вовсе не является СУБД, по крайней мере в том смысле, в котором это применимо к реляционной СУБД."
Для сравнения рассмотрим следующие замечания.
Реляционные СУБД поступают от изготовителя готовыми к использованию. Иными словами, как только система установлена, пользователи могут начать строить базы данных, писать приложения, запускать запросы и т.д.
Объектную же СУБД можно считать лишь некоторого рода набором средств построения СУБД. После исходной установки объектная СУБД не готова к немедленному использованию. Сначала она должна быть подогнана опытными специалистами, которые определят необходимые классы и методы, и т.п. Для этого предоставляется набор строительных блоков — средства для сопровождения библиотеки классов, компиляторы методов и т.д. Только после завершения такой подгонки систему можно использовать прикладным программистам и пользователям. Иными словами, результат такой подгонки уже будет больше походить на СУБД в привычном смысле этого термина.
"Кроме того, отметим, что результат подгонки такой базы будет специфическим для конкретных приложений. Эта система может подходить, например, для приложений САПР/АСУТП, но быть совершенно непригодной, например, для медицинских приложений. Иначе говоря, она все еще не стала СУБД общего назначения в том смысле, в котором реляционная СУБД является СУБД общего назначения. "
В той же статье [24.18] оспаривается так называемая идея устойчивой нечувствительности к типам из [24.2], в соответствии с которой в базу данных можно включать (изменяемые) объекты произвольной сложности.
"Для объектной модели требуется поддержка [большого количества] генераторов типа... Например, таких типов, как структура (STRUCT), кортеж (TUPLE), список (LIST), массив (ARRAY), набор (SET), пакет (BAG) и т.д... Вместе с идентификаторами объектов наличие таких генераторов типов означает, что любая структура данных, которая может быть создана в программе приложения, может быть также создана как объект в объектной базе данных, и, кроме того, такая структура объектов видна пользователю. Например, рассмотрим объект (скажем, ЕХ), который является (или обозначает) коллекцией служащих в отделе. Тогда объект ЕХ может быть реализован как связанный список или как массив, и пользователи должны будут знать, как именно реализован этот объект, поскольку соответствующие операторы доступа отличаются."
Такая вседозволенность по отношению к типам данных, сохраняемых в базе данных, — главное отличие объектной модели от реляционной модели. По сути, подходы в двух моделях можно сформулировать так.
В объектной модели можно сохранять все, что заблагорассудится, т.е. любые структуры данных, которые можно создать с помощью механизмов обычного языка программирования.
В реляционной модели, по существу, также можно сохранять все что угодно, однако требуется, чтобы то, что сохраняется, было представлено для пользователя в строго реляционной форме.
"Выражаясь точнее, в реляционной модели почти совсем ничего не говорится о том, как могут физически храниться данные... И следовательно, реляционная модель не накладывает никаких ограничений на структуры данных, которые допустимы на физическом уровне. Единственное требование заключается в том, что, если какая-либо структура реально физически сохранена, она должна отображаться в отношения на логическом уровне, а значит, быть скрытой от пользователя. Таким образом, реляционные системы проводят четкую границу между логическим и физическим представлениями, т.е. моделью данных и их реализацией, а объектные системы этого не делают. И как следствие вопреки обычному здравому смыслу объектные системы могут обеспечить значительно меньшую независимость данных, чем реляционные системы. Предположим, например, что в некоторой объектной базе данных реализация упоминавшегося объекта ЕХ, обозначающего коллекцию служащих в данном отделе, изменилась с массива на связанный список. Каковы будут последствия для существующего кода, с помощью которого осуществлялся доступ к объекту ЕХ? "