Владимир Пржиялковский

 

В PC Week/RE, № 10/98 были опубликованы материалы круглого стола под названием “Реляционная и объектная модель данных. Как сделать правильный выбор?”. Рамки публикации не позволили выразить все порожденные темой мысли, которые и стали поводом для отдельной статьи.

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

     Bill Pribyl, Steven Feuerstein. Making Sence of Object Technology in PL/SQL (Oracle Open World’97)

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

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

Соответственно дихотомии “подход хорош/плох” для двух подходов имеются к рассмотрению четыре ситуации, о которых пойдет речь ниже.

Терминологические замечания. Хотя дальше в тексте эти различия интенсивно и не эксплуатируются, было бы неплохо, чтобы читающий о них помнил: существует строгая (математическая) реляционная модель данных и существуют реальные системы (“SQL-СУБД”), построенные “по мотивам” этой модели; существует интуитивная объектная модель данных и существуют реальные объектные и объектно-реляционные СУБД, построенные “по мотивам” этой модели. Там, где ниже говорится об объектных системах, речь идет об объектных (объектно-реляционных) СУБД (а не, например, системах программирования или анализа), и где говорится об объектном подходе, речь идет об объектном подходе в СУБД. Слово “реляция” употребляется дальше для обозначения отношения в реляционной модели, являющейся, иными словами, моделью отношений (различие между отношением в реляционной теории и в математике для статьи этого уровня несущественно).    

Что каждому здорово

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

Что объектам здорово, то реляциям смерть

Приводимый здесь пример противопоставляет объектное решение, строго говоря, не реляционному, а “ER-решению”. ER-схемой можно описывать не только логику SQL - (“реляционной”) БД, но и логику БД других моделей данных, например типа CODASYL. Сам я впервые столкнулся с таким примером более 10 лет назад, именно работая с СУБД с сетевой моделью данных. По сути, он отражает неудобство отсутствия в ER-моделях более высокого уровня абстракции, нежели “сущностей” с их связями и “атрибутами” (или просто других абстракций. Здесь имеется в виду наиболее употребительный в реальных CASE-системах вариант ER-подхода, ограниченный бинарными отношениями). Однако в данном конкретном случае ограничения ER-модели наследуются SQL-системами.

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

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

Рис. 1. Сильно упрощенная ER-диаграмма структуры интегральной схемы. В связях имена и указание обязательности не фигурируют для простоты рисунка. Можно заметить, что понятие ”тип связи” ER-диаграммой, общераспространенной в существующих CASE-продуктах, не моделируется, и чтобы этот тип как-то учесть, нижнюю часть схемы придется усложнить. При этом часть модельных правил все равно не попадет на рисунок, поскольку будет представлена специально написанными процедурами физической модели

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

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

Можно заметить, что в других ситуациях, например при желании смоделировать “лицо” (“персону”, “человека”), выбор описания соответствующего лицу типа объекта не обязательно столь же очевиден. (Человек с точки зрения описания  очень сложное понятие, так что разные подсистемы даже одной и той же ИС часто требуют разных уровней абстракции для его представления. Объектный подход, в отличие от реляционного, с его механизмом представлений-view не приспособлен для работы с разными уровнями абстракции одного и того же явления.)    

Что реляциям здорово, то объектам смерть

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

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

Те, кому пример с животными покажется надуманным, могут рассмотреть другой, связанный с автопредприятием, получающим регулярно автомобили двух модификаций: бензиновые и дизельные. В соответствии с конструкцией двигателя тот или иной тип автомобиля по-своему учитывается и обрабатывается (например, имеет свои собственные атрибуты и методы). Современные технологии управления производством допускают поступление на склад продукции, опережающее связанную с ней документацию. Таким образом товар иногда сначала приходится “принять”, а уже потом только “учесть”. Если теперь у нас есть тип объектов “дизельный автомобиль” и тип “карбюраторный автомобиль” (разделенные так, потому что они обрабатываются по-разному), и нет типа “автомобиль вообще” (за ненадобностью), а также есть две операции (два метода) - “принять” и “учесть”, то по прибытии смешанной партии автомобилей, документы на которые еще не пришли, мы не сможем их сначала “принять”, а потом уже, распознав тип двигателя, “учесть” (полиморфной операции “принять” нужно сообщить тип принимаемого объекта; см. рис. 2).

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

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

Можно уточнить, что речь идет о структурной информации, так как ничто не мешает сообщить об отсутствии данных о правой задней лапе конкретной собаки NULL-значением (по крайней мере, это возможно в “объектно-расширенных” современных SQL-СУБД). Тем самым корни проблемы для объектного подхода здесь, с одной стороны, в имеющейся жесткой структурной интерпретации, отсутствующей в реляционной модели и в тесно связанных с ней SQL-системах, а с другой стороны (в отличие от реляционной альтернативы), в отсутствии теоретической основы объектного подхода, позволяющей обосновать работу с частичной информацией.    

Что смерть обоим

А вот пример реальных потребностей моделирования, с которыми не справляется ни SQL-подход, ни нынешний объектный. Пусть имеется тип записи о сотрудниках или тип объекта “сотрудник” с атрибутом “фамилия”. Данные со ссылкой на сотрудников начинают пополнять базу, но в какой-то момент сотрудница, запись о которой уже есть в БД, меняет фамилию. Часто желательно иметь информацию и о старой, и о новой фамилии. Например, это полезно при поиске, когда кто-то, не подозревая о происшедших изменениях в личной жизни этой дамы, делает запрос по ее девичьей фамилии. Или же нам важно сохранить информацию о документе, в котором есть ссылка на эту сотрудницу, с фамилией в первоначальном виде (мы хотим иметь возможность видеть на экране документ в точности в том виде, в каком он поступил в организацию). Можно обратить внимание, что:

1. Смен фамилии может быть несколько (так что второе поле здесь не спасет).

2. Подобной же изменчивости могут быть подвержены другие атрибуты сотрудников, как-то: номер телефона, адрес или имя супруга.

3. Точно так же могут изменяться сведения об организации, номенклатуре, тарифе и т. д.

Есть и более неприятные изменения. Пусть мы собираем информацию о лицах в течение длительного периода времени. База проектировалась 10 лет назад, и в ней имелся атрибут личности “партийность”. Для него был определен вполне достаточный логический тип. Через несколько лет вдруг выяснилось, что логического типа уже недостаточно, и для “партийности” требуется указывать значение из списка. Еще через несколько лет графа “партийность” в организации, ведущей базу данных, оказалась упразднена. Таким образом, для данных об одном и том же лице, относящихся к одному периоду времени, должен использоваться булев атрибут “партийности”, для данных, относящихся к другому периоду,  символьный атрибут (внешний ключ?), а для данных, относящихся к третьему периоду, атрибут должен отсутствовать (см. рис. 3). Другими примерами структурных изменений во времени могут служить упразднение атрибута “национальность” или добавление атрибута “государственный пенсионный страховой номер”.

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

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

Может показаться, что проблема не столь страшна для объектной технологии, как для реляционной, однако для современных “объектно-расширенных” в стиле SQL-3 систем она уж точно такова, как и для традиционных SQL-систем. Любой желающий может в этом убедиться, ознакомившись с описанием сегодняшних “объектно-реляционных” СУБД. Да и для “чистого” объектного подхода здесь немало трудностей, ведь речь идет не просто о том, чтобы одномоментно изменить структуру объекта (внутреннюю и, возможно, интерфейс), а о том, чтобы изменить ее для определенных интервалов времени существования объектов. Сегодняшние подходы к моделированию данных (что реляционный, что объектный) сориентированы в первую очередь на статическое моделирование прикладной области и мало рассчитаны на динамику (историю). В лучшем случае, в варианте “прилежного” исполнителя, используется практика “долго и тщательно разрабатывать схему данных, а уж потом фиксировать ее и реализовывать в ИС”, но не эксплуатируется тезис о том, что “введенные данные могут изменяться (а не только пополняться)”.    

Жизнь после смерти

Было бы неправильно завершать статью на кровожадной ноте, да и подобных пасмурных желаний в весенний день у меня нет. Конечно, упомянутые выше проблемы несколько заострены. Задачу нужно ставить более корректно и конкретно, а тогда, глядишь, иная проблема и исчезнет. Но тем не менее некоторые вполне “осязаемые” ситуации “из жизни разработчика” свидетельствуют о том, что современные модельные подходы далеко не общезначимы. Оказавшись в таких ситуациях, разработчик имеет перед собой три пути:

- не замечать возможных проблем;

- ограничить постановку задачи;

- найти паллиативное решение.

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

Возможность паллиатива объясняется тем, что в реальных системах, как правило, все же имеются некоторые средства, могущие облегчить жизнь разработчику. Можно, например, заводить журнальные таблицы, накапливающие историю производимых изменений (в одном из решений измененные поля заносятся в журнальные таблицы в унифицированном символьном виде). В каких-то случаях достаточно ограничиться добавлением в таблицу новых полей (этот способ практикуется при незначительной динамике структуры, когда “разбухание” записи некритично), и так далее. Это позволяет смоделировать некоторые качества, отсутствующие у одного или у другого подхода. Трудности такого рода моделирования, как правило, связаны с тем, что оно не поддерживается напрямую ни имеющимися СУБД, ни CASE-средствами и поэтому требует аккуратного исполнения, т. е. высокой программистской квалификации и хорошего знания СУБД. По своему уровню подобные работы приближаются к системному программированию, так как требуют самодеятельного создания специального, по сути дела CASE, инструментария.

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

В дополнение к перечисленным выше есть, правда, еще и четвертый путь. Он, выражаясь крылатой в начале перестройки фразой, состоит в том, чтобы “сменить всю систему”, т. е. предложить подход к проектированию БД, одновременно и лишенный недостатков реляционного с объектным, и сохраняющий их преимущества. Можно вспомнить, что классики мечтали об этом еще в период отрочества реляционного подхода, когда они уже видели некоторые проблематичные области использования последнего, а коммерческие фирмы-разработчики, судя по их информационным бюллетеням,  еще нет (пример: идея совмещения в одной системе реляционных явных и системных суррогатных ключей, очень близкая к реализуемому сегодня аналогичному совмещению в объектно-реляционных СУБД, фигурировала у Кодда еще в 1979 г. при описании модели RM/T, но была позже им оставлена, видимо, из-за своего рода “идейного тупика”). Нелегкая история таких модельных новшеств одновременно с их заманчивостью делают работы в направлении их поиска не только интригующими, но и трудными, объективно доступными очень немногим. Может быть, немногие из этих немногих есть и на Руси?    

Литература

Тема семантической адекватности реляционного и объектного подходов к проектированию БД и сравнения обоих подходов по их “мощности” затронута в статье без претензий на полноту и глубину. Приведено лишь три примера, понятных любому разработчику, не имеющих в существующих подходах непосредственного решения, т. е. заявлено только, что такая тема существует как предмет изучения и рассмотрения. Желающие более основательно ознакомиться с затронутыми проблемами могут для начала воспользоваться приводимыми ниже источниками, доступными на русском языке.

Что объектам здорово, то реляциям смерть

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

Э. Йордон, С. Аргила. CASE: Объектно-ориентированный анализ и проектирование*. М., Лори, 1998.

Что реляциям здорово, то объектам смерть

Литературы, относящейся к примеру из этого раздела мне неизвестно. Однако тема неполной информации в БД поднималась не раз в связи с реляционным подходом. Например, этому посвящена одна глава в книге:

Крис Дейт. Введение в базы данных. Шестое издание. Киев, Диалектика, 1998.

Там же есть ссылки на другие работы.

Что смерть обоим

Примеры возможностей, крайне необходимых в реальной практике и отсутствующих в сегодняшних системах, могут быть завуалированными формулировками типа “перспективные направления развития СУБД”, и имеются в статьях:

А. Зильбершац, С. Здоник. Стратегические направления в системах баз данных. СУБД, № 4/97.

К. Вон. Технология для объектно-ориентированных баз данных. Открытые системы, осень/94.

Жизнь после смерти

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

Дж. Смит, Д. Смит. Принципы концептуального проектирования баз данных. В сб. “Требования и спецификации в разработке программ”. М., Мир, 1984.

П. Чень. Модель “Сущность-связь”  шаг к единому представлению данных. СУБД, № 3/95.

Э. Кодд. Расширение реляционной модели для лучшего отражения семантики. СУБД, № 5-6/96. 4

К автору статьи можно обратиться по адресам: prz@deneg.net, www.ccas.ru/~prz.