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

24.5. Дополнительные аспекты

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

  • Произвольные запросы

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

  • Реализация связей

  • Языки программирования баз данных

  • Повышение производительности

  • Является ли объектная СУБД действительно СУБД

Произвольные запросы

До сих пор мы преднамеренно не подчеркивали, что если для манипулирования объектами заданы только заранее определенные методы, то произвольные запросы (не предусмотренные этими методами) просто невозможны, если только классы и методы не разработаны в соответствии со специальными правилами. Например, если для объ­екта класса DEPT определены только методы HIRE_EMP (нанять сотрудника), FIRE_EMP (уволить сотрудника) и CUT_BUDGET (урезать бюджет), то даже такой простой запрос, как "Кто является менеджером (начальником) отдела программирования", выполнить будет невозможно.

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

По нашему мнению, решение этих проблем ("специальные правила") может быть следующим.

  1. Определить множество операторов ("операторов ТНЕ_"), с помощью которых мож­но было бы получить некоторые возможные представления рассматриваемых объектов, как в главе 5.

  2. Надлежащим образом внедрить объекты в реляционную структуру. Эта часть ре­шения подробно обсуждается в следующей главе.

Однако разработчики объектных систем обычно не придерживаются данных реко­мендаций. Вместо этого они поступают следующим образом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 ссылаются на них.

В главе 8 утверждалось, что целостность данных в базе имеет фундаментальное зна­чение. Тем не менее даже те объектные системы, которые поддерживают произвольные запросы, декларативные ограничения целостности обычно не поддерживают. Выполне­ние подобных ограничений достигается с помощью процедурного кода, т.е. методов или прикладных программ. Рассмотрим, например, следующее ограничение (или "бизнес-правило") из раздела 8.5: "Поставщики со статусом меньше 20 не должны поставлять бо­лее 500 деталей". Для того чтобы обеспечить выполнение этого ограничения, в процеду­ре ее реализации должны содержаться по крайне мере следующие методы.

  • Метод для создания объекта поставки

  • Метод для изменения количества поставляемых деталей

  • Метод для изменения статуса поставщика

  • Метод для переназначения некоторой поставки другому поставщику

При внимательном изучении этого примера можно отметить важные особенности.

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

  2. Как убедиться в том, что все эти методы содержат весь необходимый для поддерж­ки целостности базы данных код?

  3. Как, например, при создании объектного класса для поставок предостеречь пользо­вателя от случайного пренебрежения методом "создания поставки" и ошибочного непосредственного использования метода NEW (т.е. без проверки целостности)?

  4. Как при изменении ограничений целостности найти и внести соответствующие из­менения во все методы, в которых они были определены?

  5. Как убедиться в корректности кода, с помощью которого приводятся в действие ограничения целостности?

  6. Как выполнить проверку целостности для отложенных (во время выполнения) операций?

  7. Как поступить с транзитными ограничениями?

  8. Как узнать обо всех ограничениях, которые заданы для данного объекта или ком­бинации объектов?

  9. Будут ли ограничения целостности приводиться в действие во время загрузки сис­темы или во время выполнения каких-либо других действий?

10. Можно ли осуществить семантическую оптимизацию (т.е. упростить запросы с по­мощью ограничений целостности так, как описано в главе 17)?

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

Реализация связей

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

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

  2. Объекты отделов могут иметь набор идентификаторов, ссылающихся на объекты сотрудников. Эта возможность соответствует подходу, использующему иерархию вложения и описанному в разделе 24.3.

  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 ООО деталей с применением заданного пользователем ме­тода для каждой детали..

  1. Случайная вставка 1 ООО деталей с присоединением каждой к трем другим.

  1. Случайное разузлование деталей (до семи уровней) с применением заданного поль­зователем метода для каждой детали, подсчитывающего соответствующие вхожде­ния в узлы.

14 Замечание относительно объектов BLOB, Хотя такой тип данных не включен в стандарт SQL/92, SQL-продукты традиционно предоставляют возможности обработки данных типа BLOB в качестве основы для работы с "большими двоичными объектами " (binary large object). Здесь объект понимается в общепринятом смысле, а не в том, который вкладывается в это по- нятие в объектных системах. Данные типа BLOB представляют собой по существу просто ка- кую-то строку байтов произвольной длины, для которой в системе предоставляется поддержка с целью организации ее хранения и извлечения; этим вся поддержка и ограничивается. Физически такие данные часто хранятся в специально отведенной для них области, отдельно от основной области хранения данных тех отношений, которые логически содержат эти данные. Данные типа BLOB могут занимать (и часто занимают) огромные области дискового пространства.

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

Согласно данным, опубликованным в [24.13], производительность некоторой (не сказано, какой) объектной системы на два порядка выше производительности некоторой (не сказано, какой) современной реляционной системы, особенно при условии, что кэш уже заполнен дан­ными (так называемый "теплый" доступ). Однако в той же работе отмечается следующее.

"Это отличие... не следует приписывать различию между собственно реляци­онной и объектными моделями... В основном, эти различия обусловлены [особен­ностями реализации]."

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

Подобная, но более обширная, тестовая программа 007 описана в [24.10].

Является ли объектная СУБД действительно СУБД?

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

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

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

  1. Совместный доступ со стороны нескольких приложений.

  2. Физическая независимость данных.

  3. Возможность выполнения произвольных запросов.

  4. Поддержка представлений и логической независимости данных.

  5. Поддержка декларативных ограничений целостности, независимых от приложений.

  6. Поддержка прав владения данными и гибкий механизм обеспечения их защиты.

  7. Управление совместным доступом.

  8. Каталог общего назначения.

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

"Впоследствии, после представления основной идеи хранения объектов в базе данных, эти возможности были рассмотрены и реализованы как усовершенст­вования и дополнения к исходной объектной модели... Один из важных выводов... заключается в том, что объектная СУБД и реляционная СУБД— системы, ко­торые различны по сути. На самом деле можно было бы доказать, что объ­ектная СУБД фактически вовсе не является СУБД, по крайней мере в том смысле, в котором это применимо к реляционной СУБД."

Для сравнения рассмотрим следующие замечания.

  • Реляционные СУБД поступают от изготовителя готовыми к использованию. Иными словами, как только система установлена, пользователи могут начать строить базы данных, писать приложения, запускать запросы и т.д.

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

"Кроме того, отметим, что результат подгонки такой базы будет специ­фическим для конкретных приложений. Эта система может подходить, например, для приложений САПР/АСУТП, но быть совершенно непригодной, например, для медицинских приложений. Иначе говоря, она все еще не стала СУБД общего назначения в том смысле, в котором реляционная СУБД явля­ется СУБД общего назначения. "

В той же статье [24.18] оспаривается так называемая идея устойчивой нечувстви­тельности к типам из [24.2], в соответствии с которой в базу данных можно включать (изменяемые) объекты произвольной сложности.

"Для объектной модели требуется поддержка [большого количества] генера­торов типа... Например, таких типов, как структура (STRUCT), кортеж (TUPLE), список (LIST), массив (ARRAY), набор (SET), пакет (BAG) и т.д... Вместе с иден­тификаторами объектов наличие таких генераторов типов означает, что лю­бая структура данных, которая может быть создана в программе приложения, может быть также создана как объект в объектной базе данных, и, кроме того, такая структура объектов видна пользователю. Например, рассмотрим объ­ект (скажем, ЕХ), который является (или обозначает) коллекцией служащих в отделе. Тогда объект ЕХ может быть реализован как связанный список или как массив, и пользователи должны будут знать, как именно реализован этот объ­ект, поскольку соответствующие операторы доступа отличаются."

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

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

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

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

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