Сегодня 24.04.2024 Вы зарегистрированы в системе под именем ANONYMOUS

Rambler's Top100
Начало
Обо мне
Моя семья и звери
Статьи
Проекты
Стихи
Фото-галерея
Досуги
Былое и думы
Универсальная Самообучающаяся Экспертная Система
Мудрости
Приколы
 
Новости
Карта сайта
Все материалы
Обсуждение
Опросы
 


КиноНавигатор поможет выбрать фильм, если не знаешь, что посмотреть.
Персональный сайт Андрея Акопянца  >  Статьи  >  Корпоративная автоматизация

    След. материал >>

Автоматизация хаоса – 3, или пять лет спустя

"Ничто не мешает мне сегодня быть умнее, чем я был вчера"

Б. Шоу

Со времени написания моих предыдущих статей по корпоративной автоматизации (''Автоматизация хаоса'', ``Блеск и нищета клиент-серверных технологий'', ``Автоматизfция хаоса-2'') прошло почти пять лет. И жизнь моя сложилась так, что корпоративными системами я все это время не занимался, а занимался в основном разнообразными веб-проектами.

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

И случилось как в известном анекдоте - когда на военном заводе попробовали выпускать швейные машинки, а получался у них все равно автомат Калашникова.

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

Я перечитал свой основополагающий труд (Автоматизация Хаоса-2 - далее АХ2) и понял, что он немножко устарел - не в части подхода (прикладная система как проблемно-ориентированный редактор данных), а в описании используемой метамодели.

Проектирование от данных

(краткое содержание предыдущих серий)

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

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

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

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

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

В материале АХ2 была описана метамодель, которую я в течение нескольких лет успешно применял как методологию для проектирования и реализации ряда корпоративных систем. Эта модель была рефлексией опыта проектирования типичных СУБД-шных приложений в Windows-like.

Но инструментальной реализации, т.е. системы, позволяющей описать модель предметной области в терминах метамодели, и на выходе получить готовое работающее приложение, для АХ2 создано не было.

Communiware

А уже упоминавшаяся мной платформа Communiware, ядро которой было разработано под моим руководством в 1999-2000, как раз явилась такой инструментальной системой, ориентированной на создание web-приложений.

Изначально Communiware проектировалась как система, которая позволила бы в едином концептуальном базисе поддержать все типичные для веб-сайтов информационные структуры, как то:

- иерархию разделов/подразделов с публикациями

- ленты новостей

- комментирование публикаций, гест-буки, форумы, веб-логи и др.

- товарные каталоги

- и др.)

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

Используемая в Communiware метамодель по необходимости (ведь делать надо было, а не только теоретизировать :) существенно менее абстрактна, чем то, что описано в "Автоматизации хаоса-2", и предполагает вполне определенную каноническую реализацию в виде структуры БД, регулярным образом расширяемой при настройке на модель предметной области.

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

Модель Communiware (далее - CW) на практике продемонстрировала свою универсальность и вполне приемлемую эффективность. На ее базе были реализованы десятки (если не сотни) самых разнообразных Интернет-проектов - от простых информационных сайтов и Интернет-магазинов до промышленных b2b-порталов.

И я сейчас смело могу рекомендовать эту модель для гораздо более широкого круга задач, чем создание сайтов.

Унификация объектов

Использование модели "сущность-связь" для проектирования структур баз данных давно стало общим местом. Модель "сущность-связь" лежит также и в основе модели CW.

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

Но в модели CW чуть-чуть усилились требования к идентификатору объекта - требуется, чтобы он был уникален среди всех объектов системы, а не только среди однотипных с ним. А лучше всего - обеспечить world-wide уникальность идентификатора.

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

Это требование фактически означает, что все объекты системы являются потомками (в смысле объектного наследования) некоторого базового понятия "Объект".

Предполагается явное существование таблицы-перечня всех объектов, в которой хранится ключ (идентификатор) объекта, идентификатор типа, имя и другие атрибуты, общие для объектов всех типов.

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

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

<ID объекта><Id атрибута><значение>.

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

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

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

Материализация связей

А вот с понятием связей произошла существенное изменение - в модели CW они "материализовались".

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

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

В более сложном случае (многие ко многим) для реализации связи требуется промежуточная таблица. Можно, конечно, ее связью не считать, а считать другой сущностью (Отношением, как было сделано в модели АХ2) тем не менее концептуально это часто все-таки является связью.

Неприятный промежуточный случай возникает, когда связь, скажем, 1:N, но требуется поддерживать явно заданный порядок потомков.

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

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

В модели CW эта проблема решена радикально - связь там это не абстрактное понятие, а вполне конкретная запись в конкретной таблице.

Т.е. в БД в явном виде присутствует таблица "Связи", хранящая все связи всех объектов, и в простейшем случае имеющая структуру

<объект-предок><объект-потомок><тип связи>

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

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

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

Описание типов связи

Связи в модели CW несимметричные, т.е. один из связанных объектов считается ПРЕДКОМ по этой связи, другой - ПОТОМКОМ. Свзяь направлена от потомка к предку.

Вообще говоря, тип связи характеризуется:

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

2. Мощностью связи -1:1, 1:N, M:N

3. Признаком транзитивности (об этом поговорим дальше) или симметричности (снимающим различие между предком и потомком).

4. Перечнем типов, которые могут выступать в этой связи как предки и как потомки

(тип1, тип2, тип3...) --> (тип4,тип5,...), причем таких наборов в описании связи может быть несколько, т.е. нужно уметь ограничивать - какие типы (попарно) могут быть связаны этой связью. Скажем, если мы создали связь Вышестоящий/Подчиненный, мы можем сказать, что допустимые типы для нее это

Персона -> Персона

Организация -> Организация

можно, конечно, задействовать еще вариант

Организация -> Персона

отражая таким образом функцию руководителя, но вариант Персона -> Организация мы считаем бессмысленным, что и не позволяет нам написать

(Организация, Персона) -> (Персона, Организация)

5. Признаком обязательности для отдельных типов - т.е. указание, что какие-то типы обязаны иметь предков/потомков по этому типу связи. (впрочем, это можно считать и атрибутом типа, а не связи)

6. В принципе, связи можно снабжать дополнительными атрибутами, хранящимися, как и для типов, в отдельных таблицах для разных типов связи. Это сильно повышает мощность модели, позхвояля напрямую реализовать в ней то, что в АХ2 называлось "отношение", но это заметно утежеляет реализацию. Скажем, в канонической реализации CW это сделано не было (впрочем, там еще кое-что из перечисленного выше не было сделано, увы).

А вот нагрузить ВСЕ связи дополнительным строковым атрибутом и порядковым номером потомка и несложно, и полезно. Т.е. на практике таблица связей имеет структуру

<объект-предок><объект-потомок><тип связи><порядковый номер><параметр>

Транзитивные связи и метасвязи

Существенным пробелом в модели АХ2 было отсутствие понятия иерархии. Точнее, она там упоминалась как возможная иерархия типов объектов, но не боле того. Даже иерархические справочники не были там помянуты.

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

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

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

Транзитивностью в математике называется свойство отношения, при котором если

A ~ B & B ~ C, то A ~ C

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

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

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

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

Т.е. таблица транзитивного замыкания имеет структуру

<потомок><предок><тип связи><расстояние>

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

Это решается введением понятия МЕТАСВЯЗИ. Метасвязь описывается набором типов связей (не обязательно транзитивных). И для метасвязей также создаются записи <предок>-<потомок> в таблице транзитивных замыканий, если существует путь от потомка к предку по связям, входящим в метасвязь.

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

Описание модели предметной области

В модели CW описание предметной области включает в себя

- набор атрибутов базового объекта

- описание набора типов

- описание атрибутов

- описание связей

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

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

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

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

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

Проблема эффективности

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

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

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

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

3. Для тех связей (1:1) и (1:N), для которых скорость извлечения связанных данных критична, можно реализовать механизм "контролируемой денормализации", т.е. включить в состав потомков дополнительные атрибуты для идентификатора связанного объекта (и возможно, его названия), и использовать именно эти поля для извлечения связанных данных .

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

Заключение

Как я недавно узнал, реализованная в 1996 году под моим руководством система автоматизации учета брокерской конторы (использующая метамодель АХ2) до сих пор используется в бэкофисе ИБГ ``НИКойл'', несмотря на многочисленные попытки заменить ее вроде как более продвинутыми системами - все они оказывались при ближайшем рассмотрении недостаточно гибкими.

Т.е. говоря цитатами из классиков, ``практика - критерий истины'' показала, что ``идеология марксизма-ленинизма непобедима, потому что она верна!''. Думаю, что системам на базе изложенной в этой статье методологии суждена не менее долгая жизнь, потому что она тоже верна, и с моей сегодняшней точки зрения, даже гораздо более верна


( написано 17.03.2004,   опубликовано 17.04.2005)
    След. материал >>

Обсуждение (нет реплик)    Настройка



В начало страницы (C) Andrey Akopyants
Перепечатка авторских материалов сайта приветствуется! Ссылка на первоисточник при перепечатке обязательна.