Опубликован: 23.10.2005 | Доступ: свободный | Студентов: 4086 / 201 | Оценка: 4.44 / 4.19 | Длительность: 33:04:00
Специальности: Программист
Лекция 13:

Сохранение объектов и базы данных (БД)

Основания ОО-баз данных

Становление ОО-БД подкреплялось тремя стимулами.

  • D1 Желанием предоставления разработчикам ОО-ПО механизма сохранения объектов, сопоставимого с их методом разработки и устраняющего сопротивление несогласованности.
  • D2 Необходимостью преодоления концептуальных ограничений реляционных баз данных.
  • D3 Возможностью предложения более развитых средств работы с базами данных, отсутствующих в ранних системах (реляционных и других), но сделавшихся возможными и необходимыми благодаря прогрессу технологии.

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

Изучение понятия ОО-БД начнем с выявления ограничений реляционных систем D2 и того, чем они могут не устроить разработчиков ОО ПО (D1), а затем перейдем к новаторским достижениям движения за ОО-БД.

На чем застопорились реляционные БД

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

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

Типичным примером является БД с данными о налогоплательщиках с большим количеством объектов, представляющих людей, описываемых фиксированными компонентами: ФИО (строка), дата рождения (дата), адрес (строка), зарплата (число) и еще несколько свойств.

Свойство (R3) исключает многие приложения, связанные с мультимедиа, CAD-CAM и обработкой изображений, в которых некоторые элементы данных, такие как битовые образы изображений, имеют сильно различающиеся и иногда очень большие размеры. Этому также мешает требование, чтобы отношения находились в "нормальной форме", налагаемое существующими коммерческими системами, из-за которого один объект не может ссылаться на другой. Это, конечно, очень сильное ограничение, если сравнить его с тем, что мы доказали раньше в дискуссиях этой книги.

Как только у нас есть некоторый объект, ссылающийся на другой объект, то ОО-модель обеспечивает простой доступ к непрямым свойствам этого объекта. Например, redblack.author.birth_year возвращает значение 1783, если переменная redblack присоединена к объекту слева на рис. 13.5. Реляционное описание неспособно представить поле со ссылкой author ( автор ), чьим значением является обозначение другого объекта.

Объект со ссылкой на другой объект

Рис. 13.5. Объект со ссылкой на другой объект

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

Для ответа на вопросы вида: "В каком году родился автор "Красного и черного"?" реляционная реализация должна будет вычислять соединения, проекции и т. п. В данном случае можно использовать указанное выше соединение, а затем взять его проекцию на атрибут birth.

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

Идентичность объектов

Простота реляционной модели частично объясняется тем, что объекты однозначно идентифицируются значениями своих атрибутов. Отношение (таблица) является подмножеством декартового произведения A x B x ... некоторых множеств A, B, ...; иными словами, каждый элемент отношения, каждый объект, это кортеж < a1, b1, ...>, в котором a1 принадлежит A и т. д. Поэтому он не существует вне своего значения, в частности, вставка объекта в отношение не будет иметь никакого эффекта, если в отношении уже имелся идентичный кортеж. Например, вставка < "The Red and the Black", 1830, 341, "STENDHAL" > в приведенное выше отношение BOOKS не приведет к изменению этого отношения. Это сильно отличается от динамичной модели ОО-вычислений, в которой могут существовать два идентичных объекта.

Напомним, что отношение equal (obj1, obj2) истинно, если obj1 и obj2 - это ссылки, присоединенные к этим объектам, но равенство obj1 = obj2 будет ложным.

Быть идентичными - не значит быть одними и теми же (спросите об этом близнецов). Такая способность различать два этих понятия частично определяет силу моделирования в ОО-технологии. Она основана на понятии идентичности объекта: всякий объект существует независимо от его содержания.

Отдельные, но равные (обе нижние ссылки присоединены к одному объекту)

Рис. 13.6. Отдельные, но равные (обе нижние ссылки присоединены к одному объекту)

Посетителям Императорского дворца в Киото говорят, что эти здания очень древние и каждое перестраивается приблизительно раз в сто лет. С учетом понятия идентичности объекта в этом нет никакого противоречия: объект остается тем же, даже если его содержание меняется.

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

Разумеется, в реляционной модели тоже можно выразить идентичность объектов: достаточно добавить к каждому объекту специальное ключевое поле с уникальным для объектов данного типа значением. Но придется об этом заботиться явно. А в ОО-модели идентичность объектов имеется по умолчанию.

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

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

Пороговая модель

Из предыдущих обсуждений можно вывести то, что может быть названо пороговой моделью ОО-БД: минимальное множество свойств, которым должна удовлетворять система БД, чтобы заслужить название ОО-БД (по работе [Zdonik 1990]). (Другие, также весьма желательные, свойства будут обсуждены ниже.) Имеется четыре требования, которым должна удовлетворять пороговая модель: база данных, инкапсуляция, идентифицируемость объектов и ссылки. Такая система должна:

  • T1 предоставлять все стандартные функции баз данных, перечисленные выше в этой лекции;
  • T2 поддерживать инкапсуляцию, т. е. позволять скрытие внутренних свойств объектов и делать их доступными через официальный интерфейс;
  • T3 связывать с каждым объектом его уникальный для данной базы идентификатор;
  • T4 разрешать одним объектам содержать ссылки на другие объекты.

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

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

Дополнительные возможности

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

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

Версии объекта

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

Некоторые ОО-СУБД справляются с этой проблемой, трактуя каждую модификацию объекта как создание нового объекта, тем самым, поддерживая доступ к старым версиям объектов.

Версии классов и эволюция схемы

Объекты - это не единственные элементы, для которых требуется поддержка версий: со временем могут изменяться и порождающие их классы. Это проблема эволюции схемы, которая обсуждалась в начале этой лекции. Только очень немногие ОО-СУБД полностью поддерживают эволюцию схем.

Длинные транзакции

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

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

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

Хотя длинные транзакции концептуально могут и не требовать использования объектной технологии, усилия последнего времени по их поддержке пришли со стороны ОО-СУБД, некоторые из которых предлагают способ проверки любого объекта как в базе данных, так и вне нее.

Блокировка

Каждая СУБД должна предоставлять некоторую форму блокировки объектов для того, чтобы обеспечить безопасный параллельный доступ и обновление. Ранние ОО-СУБД поддерживали блокировку на уровне страниц, при которой границы блокируемой области определялись операционной системой. Это было неудобно как для больших объектов (которые могут занимать несколько страниц), так и для маленьких (которых может быть много на одной странице, так что блокировка одного из них повлечет блокировку и остальных). Новые системы предлагают блокировку на уровне объекта, позволяя приложению клиента блокировать объекты индивидуально.

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

Запросы

Как было подчеркнуто выше, СУБД поддерживают запросы. Здесь ОО-системы в случае эволюции схем могут оказаться более гибкими, чем реляционные. Изменение схемы реляционной БД часто означает необходимость изменения текстов запросов и их перекомпиляцию. В ОО-БД запросы формулируются относительно объектов; вы спрашиваете о некоторых компонентах экземпляров некоторого класса. Здесь в качестве экземпляров могут выступать как прямые экземпляры данного класса, так и экземпляры его собственных потомков. Поэтому, если у класса, для которого сформулирован запрос, появляется новый потомок, то данный запрос применим и к экземплярам этого нового класса и позволяет извлекать из них требуемую информацию.