Pull to refresh

Comments 58

Отличная статья, спасибо, буду ждать продолжения.

Хотелось бы немного технических подробностей. Какие СУБД, какие средства доступа к данным удобнее применять.
Как по мне, особых ограничений нет, разве что СУБД нужна серьезная — MySQL вряд-ли будет нормально работать, много JOIN'ов.
> «много JOIN'ов»
Необязательно использовать Join'ы. есть другой подход составления запросов
Есть подход при котором запросы можно составить так, данная структура будет нормально работать в MySQL?
Минус такой структуры — это падение производительности, даже на сравнительно простых операциях — даже чтоб получить значение какого-нибудь атрибута объекта потребуется несколько соединений. Потому для реализации нужны мощные СУБД — PostgreSQL, Oracle.
Я так понимаю логичнее иметь в СУБД уровень представлений (VIEW), и к нему уже делать SQL-запросы уровня бизнес-логики. Многие СУБД позволяют делать индексированные VIEW. Firebird, например.
Во-первых, такой уровень представлений резко увеличивает количество работы над БД. Но это еще ладно.

Хуже то, что индексированные view — это немалая просадка по производительности при добавлении/изменении записи.
1. увеличивает работу над БД но уменьшает работу над клиентом. Хотя вместо VIEWшек возможно, лучше будет использовать динамически генерируемые SELECT'ы

2. Зато выигрыш в SELECT'ах. Это проблема не вьюшек а индексов вообще. Естественно нужен сбалансированный подход
«увеличивает работу над БД но уменьшает работу над клиентом.»
Мне показалось, что вся статья о том, как уменьшить работу над БД при сложной предметной области.

«Хотя вместо VIEWшек возможно, лучше будет использовать динамически генерируемые SELECT'ы»
Тогда вернемся к тому, с чего начали — повышение требований к СУБД с точки зрения производительности сложных запросов.

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

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

(Entity-Value, правда, еще сильнее, но это детали)
>>Короче, речь о том, что такая модель заведомо сильнее загружает базу, нежели обычная.
это верно

Впрочем, зарплата программиста однозначно превысит расходы на любой мощный сервер в долгосрочной перспективе. А вот если решение тиражируемое, то тут не все так однозначно
А если метамодель и метаданные хранить в объектной базе, а фактические данные держать в реляционной, при этом генеря DDL и SQL из метаданных и метамодели?
… то получится современный ORM с миграциями, только маппинг лежит в БД. И на миграциях вы убьетесь.
За годы разработки прикладных систем у меня сложилось устойчивое мнение, которое конечно может оказаться неверным, что надо наоборот уменьшать работу над БД, ибо это приводит к использованию стыка технологий (SQL -> C# (Java)) намного чаще, что влечет к ошибкам переключения между этими двумя контекстами.

Если же избавить прикладного программиста от рутинной работы с БД, то это будет качественный скачок в разработке.
Я в целом поддерживаю, с точки зрения дизайна ПО, SQL-запросы конечно портят всю картину.
Однако, с точки зрения производительности куда ж без работы с БД? По специфике моей работы, наши продукты разворачивают порой на весьма убогом железе, где производительность СУБД является уже решающим фактором.
Это часто приводит к тому, что многие программисты просто не умеют использовать даже половины возможностей СУБД считая ее «тупым» хранилищем, из-за чего при работе с более-менее серьезными объемами данных приложения нещадно тормозят. В приложениях, которые ориентированы на работу с данными нужно очень внимательно относится к СУБД и стараться использовать их возможности по максимуму, хотя, естественно, такие решения менее универсальны, но как говорит один мой знакомый: «чем круглее кирпич, тем сложнее из него строить дома».
Существует подход, когда данная система используется только на периоде разработки, например, базы данных. А затем полученная схема «выгружается» в традиционную модель данных. Таким образом, получаем гибкость на периоде разработки и хорошую производительность в итоге. Но в данном случае, насколько я понимаю, речь идет о модели более близкой к т.н. Технологии Активных Объектов (отечественные разработки) и Active Object Modeling (зарубежной), ориентированных на быстро меняющийся бизнес.
>>Существует подход, когда данная система используется только на периоде разработки, например, базы данных

очень интересная идея, как-то сам не догадался
Ну статические предметные области, для которых разработаны известные подходы уже не вызывают сложностей. Более того, классика встречается все реже, т.к. мир меняется более динамично и приходится или руками переделывать все время (что и происходит с общепринятыми подходами) или же придумывать новый тип автоматизации разработки, мне видится, что для БД — это должен быть путь введения метамоделей N-ного уровня (моногомерных абстракций). Это лучше чем реинжениринг всей БД при повышении гибкости.
А вы изучали модели, названия которых приведены в предыдущем комментарии? Просто ваш подход очень напоминает их. По этому поводу существует много статей, в которых описаны области применения, а также проблемы реализации.
И по поводу статических предметных областей также существует много нерешенных проблем.
Наверно, я не достаточно раскрыл в статье, почему нагрузка не увеличится (или увеличится несущественно): в базу будут одновременно храниться несколько абстрактных слоев, то есть, классическая структура таблиц не поменяется, просто к ней еще добавится параллельно существующая структура с более высокими абстракциями. То есть, если у нас есть «Сотрудники», «Руководители» и «Персоны» — это три разных слоя. Не всякий сотрудник является руководителем, не всякая персона является сотрудником. Если мы хотим работать с сотрудниками, не заботясь о том, руководители они или исполнители, то в запросах будет фигурировать один уровень абстракции, если нам нужно работать с персонами (то есть со всеми физическими лицами) то в запросах будут таблицы более абстрактного слоя. Поэтому, такую штуку можно навернуть сверху почти на любую структуру БД. Единственные изменения, которые я вношу в нижние слои абстракции, это:
— Во всех таблицах с сущностными будет не отдельный автоинкрементный ID, а сквозной на всю БД
— Все таблицы, ссылающиеся на сущности любого порядка имеют Foreign Key указывающий на одну и ту же таблицу — на таблицу сущностный.
Все же остальные связи в БД не меняются, например у справочников и логов, будут свои автоинкрементные Primary Key.
то есть, если у нас есть «Сотрудники», «Руководители» и «Персоны» — это три разных слоя

Что-то не совсем понятно как это на уровне таблиц реализуется. Т.е. «руководитель» это СОТРУДНИК JOIN специфические_аттрибуты_руководителя?
Там получаются не совсем таблицы в традиционном понимании. Абстрактный подход позволяет укладывать разные струткры данных, не ограничиваясь традиционными реляционными или объектно-реляционными
Я тоже так предполагал по началу, но ТС пишет о том что
классическая структура таблиц не поменяется, просто к ней еще добавится параллельно существующая структура с более высокими абстракциями

вот это и не понятно. релизация на уровне таблриц БД интересна. На пальцах, если можно.
На пальцах слишком много получится. Можно посоветовать почитать про Технологию Активных Объектов и Active Object Modeling. Ну и про EAV и универсальную модель данных для более общих подходов.
В конце статьи прикрепил еще схему, где показаны все аспекты моделирования сущностей с использованием метамоделей, которые удалось собрать за последние 10 лет практического применения этих методов. В нижней строке белым помечены блоки, которые реализованы в СУБД, а серым, которых в СУБД нехватает для построения полноценных приложений на основе динамически-интерпретируемых метамоделей.
Каждый слой хранит только свои специфические атрибуты, поэтому у нас получается еще один аспект хранения «группа атрибутов». Группироваться они могут по уровню абстракции, по языку, по периоду валидности, по применению в задачах и еще по многим вещам. Если нам нужно выбрать из базы весь «профиль сущности», то мы делаем несколько независимых SELECT-ов, каждый из них отдает одну или несколько групп. Например экземпляров сущности «Паспорт» может быть несколько для каждого экземпляра «Персона», а вот «личное дело» в отделе кадров одно, а адресов может быть у него много да еще и каждый адрес может быть на нескольких языках. Я думаю JOIN тут не нужны. Лучше всего вынимать это несколькими запросами. Но случаев, когда мы работаем сразу с нескольким уровнями абстракции очень мало, чаще всего прикладная задача требует доступ только к одному аспекту сущности, поэтому SQL-запросы почти не изменятся.
теперь примерно понял, спасибо
Интересная идея, но ведь по сути получается что метамодель — это и есть метаданные структуры базы. Тот же MS SQL Server хранит все эти метаданные, и при желании их можно легко извлечь из базы и получить ту самую метамодель. Далее, анализируя метамодель, система может сама адаптироваться к изменениям.
Фокус в том, чтобы «на лету» менять эти метаданные с минимальными расходами
В таком случае надо писать свой редактор метамодели, который будет удобен и практичен во всех случаях.
Тут нужен скорее интерпретатор или транслятор такой модели. И он будет подходить далеко не для всех случаев. Кроме того, возникает очень много проблем такой реализации. Мы как раз проводим исследования на эту тему: www.interface.ru/home.asp?artId=24052
можно, но редактирование встроенной метамодели БД это очень затратный процесс, если нужно сделать что-то сложнее чем новое поле в таблице. Т.е. это перстройка индексов, перекачка данных между таблицами, генерация значений по-умолчанию и другие неприятные вещи.
СУБД не поддерживает многих аспектов метамодели, об этом будет вторая часть статьи. Например, когда у нас есть связь многие-ко-многим мы не можем по Foregn Key метаданным понять, является ли эта связь: Master-Detail или же это связь со справочником, или же с помощью этой связи построена многоязычность одной и той же сущности или связь представляет нечто другое. Всего типов связей, на которые можно разложить один единственный Many-to-Many есть два десятка, и по типу связи можно многое в приложении построить динамически и гибко. Таким образом метамодель в какой-то части повторяет метаданные в СУБД, а в какой-то части их дополнет или переопределяет.
Согласен про типы связей — это на уровень СУБД не имеет смысла выносить.

Теория смотрится очень даже неплохо. Но главная загвоздка тут будет в практической реализации анализатора метамодели.
О! У нас в команде уже последние 10 лет все разрабатывается с применением элементов метамодели, но полной реализации пока нет, вот готовим фреймворк в данный момент, будет оупен-соурсным, дам на ознакомление )
на каком языке/фрэймворке?
Ранее это были Delphi и C#, теперь перешли на PHP и Java. Планируется поддержка разных языков, в т.ч. JavaScript+Node.js
Вот про фреймворк очень интересно. Сами в команде тоже готовим нечно подобное, но немного с другой стороны подходим к решению тех же проблем.
Основная идея такая:
— берем готовую структуру реляционной базы и автоматически экстрактим из нее метаданные
— доописываем метаданные, которых не хватает, чтобы построить полноценную метамодель
— таким образом имеем два и более слоя абстракции в базе
— если нужно менять структуру базы, то имеем специальную админку, где управляем метаданными, а структура в базе модифицируется уже автоматом
— при передаче данных между системами, передаем данные + часть метамодели, включая струкутру, шаблоны, интерфейсы, поведение
— часто используем динамическую интерпретацию метамодели, в частности, для динамического построения интерфейсов пользователя и гибкого сетевого взаимодействия
Есть такой продукт ASP.NET Dynamic Data — он как раз использует эти данные из MS SQL Server.
если я правильно понял, разнообразные типы данных (числа, строки и т.п.) будут храниться физически в одной таблице БД? Или делаете несколько хранилищ для разных типов?
В параметрических базах данных все атрибуты сущностей сливают или в одну таблицу или делают по таблице на каждый тип данных. Но это приводит к тому, что таблица-хранилище разрастается, его невозможно эффективно индексировать (в индекс попадают лишние данные) и нарушается реляционный принцип. По сути — все преимущества реляционного подходя теряются, запросы красиво строить уже нельзя, толпы JOIN-ов. Такие БД как раз получаются, как один из видов решения проблемы стыковки объектно-ориентированного программирования и реляционного подхода в СУБД. Но эффективны они только когда данных мало. Если мы имеем миллионы и сотни миллионов записей в таблицах, то тут уже ООП должно прогнуться под СУБД, вплоть до частичного отказа от принципов объектного подхода.
Добавлю еще пару ссылок по теме:
Статья «Потерянная семантика» — blog.meta-systems.com.ua/2009/11/blog-post.html
Статья «Интеграция на уровне вызовов или мета-данных?» — blog.meta-systems.com.ua/2009/10/blog-post_18.html
Статья «Введение мета-уровеня» — blog.meta-systems.com.ua/2011/01/blog-post.html
Статья «Метамодель в задачах интеграции информационных систем» — blog.meta-systems.com.ua/2010/07/blog-post.html
Слайд к докладу «Слой ИС с динамической интерпретацией метаданных» — blog.meta-systems.com.ua/2011/01/blog-post_28.html
И еще ссылки на Хабре:
Статья «Интеграция информационных систем» — habrahabr.ru/blogs/refactoring/117468/
Мне показалось, что по ссылкам какой-то развод.
Это все очень клево, только не понятно зачем это все надо.


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

В этом случае помогает очень простая вещь, упрощение предметной области путем выделения в ней специфичных предметных областей и связей между ними. Связи при этом должны быть выбраны так чтобы никоим образом не зависеть от специфичной области. При этом сама специфичная область от таких связей зависеть может. Банальный пример в рамках биллинга «услуга», понятно что услуга телефонной связи и услуга предоставления доступа в интернет обладают специфичными для них атрибутами, но так же у них есть и общие не специфичные. Они выносятся выше, а специфичные уже содержат связи с услугой.
Именно так, обобщение и повышение абстракции модели даже на один уровень, позволяют охватить в 10 раз больше различных предметных областей, отличающихся спецификой. А разработка информационных систем должна сводиться не к количественной эскалации использования паттернов, а к двум параллельным процессам: абстрагирование и индивидуализация. Где абстрагирование — это повышение абстракции, а индивидуалтзация, это реализация специфического функционала уже в рамках абстрактной модели более высокого порядка.
А вот попроще писать ну никак? Особенно вот UML сильно в тему тут. Большей части разработчиков двух уровней более чем за глаза, причем реализуемых при помощи механизма схем.
Это статья не про готовую технологию, а для разработчиков технологий. Когда будет релиз инструмента для разработки прикладных систем, то я его опишу простым языком. Там даже про уровни абстракции ничего не будет сказано, хочется сделать инструмент, приближенный к пользователю и с использованием популярной или бизнес- лексики.
С такими темпами мы переучим Хабр использовать научную лексику и стиль статей)
Это статья не про готовую технологию, а для разработчиков технологий. Когда будет релиз инструмента для разработки прикладных систем, то я его опишу простым языком. Там даже про уровни абстракции ничего не будет сказано, хочется сделать инструмент, приближенный к пользователю и с использованием популярной или бизнес- лексики.

Этой затеей уже занимаются не один год куча народу, в том числе и IBM. Пока ничего кроме жирного тормозного монстра мало применимого в реальной жизни никто не сделал. И тут вы на белом коне говорите мы то ух? Что-то мне слабо верится.

С такими темпами мы переучим Хабр использовать научную лексику и стиль статей)

Как говорил мой преподаватель математики, если вы не можете объяснить для бабушки грош цена вам как специалисту. Вот в данный момент мне более менее понятно про что статья, но вот зачем даже с учетом замечания о разработчиков технологий не понятно. Конкретных то методик не описано. Как выделять, почему стоит выделять именно так увы не указано.
Будет вторая часть статьи и есть ссылки на другие. Я ж не говорю, что мы так раз и все решили, мы уже более 10 лет понемногу реализуем, натыкаемся на проблемы и ищем решения, даже более эмпирическими методами, нежели логическими. Абсолютного решения не предлагаем, но некоторый пригодный к использованию подход есть.
Главное чтобы в вашей статье второй столько воды как в этой не было. Тут вот большая часть просто не поняла про что все это и зачем. Они нормальную форму Бойса-Кодда не осилили а вы тут им такую инфу да еще в таком тяжелом виде.
Еще по поводу IBM, а именно Lotus/Domino — думаю, что это одна из наиболее удачных и долгоиграющих систем с использованием динамической интерпретации модели. Система уже давно не имеет развития и новых версий более не будет, но на старых продуктах до сих пор решаются прикладные задачи такого уровня, как «современным» технологиям и не снилось. В общем, IBM-у респект.
Еще по поводу IBM, а именно Lotus/Domino — думаю, что это одна из наиболее удачных и долгоиграющих систем с использованием динамической интерпретации модели.

Lotus/Domino то каким сюда боком? Буквально недавно на opennet публиковали информацию о новой системе IBM основанной на рисовании бизнес-правил. Я вот про нее. А Lotus/Domino все же хотя модель использовала эту была немного не про то. Ну и то что ее поддержку прекратили тоже как бе говорит нам, что не настолько он был удачен.
Классический подход предусматривает разработку структур баз данных, где все сущности информационной модели находятся на одном абстрактном уровне, являются однородными. Однако, сложные и слабо-структурированные предметные области приводят реляционную декомпозицию к комбинаторному взрыву, непропорциональному росту количества таблиц и связей. А динамические предметные области, в которых ежедневные изменения являются нормой жизненного цикла, требуют постоянного реинженеринга структуры реляционной базы данных.

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

Подменив предметную область метамоделью, вы сможете извлекать из базы лишь утверждения касающиеся этой самой метамодели, а не вашей предметной области. Следовательно, лисапедить логический уровень метамодель будет самостоятельно. В общем случае это сложнее, чем кажется на первый взгляд (попробуйте реализовать пресловутый ACID). А в тривиальных — NoSQL в руки. =)
В РСУБД и так лежат метаданные, вопрос только в том, чтоб их дополнить.
Абстрактную модель второго уровня предлагается хранить в БД параллельно с базовой абстракцией.
Таким образом, мы полностью используем развитый аппарат реляционной алгебры и на базовом слое и на слое абстракции второго уровня. Связь между слоями предполагается через введение сквозного первичного ключа, общего для той части таблиц, которая представляет сущности.
Информационная модель в РСУБД содержит, например, атрибуты сущностьей, типы атрибутов, связи сущностьей, и т.д. но такие вещи, как атрибуты связей или группы атрибутов или группы связей и т.д. (см последнюю иллюстрацию в статье) можно реализовать только надстройками.
А где описывается сам выполняемый код для работы с данными — логика приложения? В ней возможны ссылки на системные справочники.
Например — есть форма заявки на что-либо с несколькими полями. Выбираем значение поля, например, «тип продукта» — и в зависимости от значения другое поле на этой форме становится видимым или нет.
В нашем текущем проекте это всё тоже метаданные.
Если структура и параметры данных меняются динамически, то бессмысленно компилировать логику приложения и фиксировать ее таким образом. Как я предлагаю в статье про метамодели, можно выделить обобщенную логику (абстрактную модель или метамодель), она привязана не к конкретной задаче, а к широкому классу задач, вот ее нужно компилировать. Но выделенные в ходе абстрагирования метаданные могут содержать не только модификации для структуры и параметров данных, но и модификации для логики, для активного (или императивного) способа обработки, выражаемые в сценариях на динамических языках программирования. Эти самые языки мы можем разрабатывать под задачу и встраивать в свое ПО или брать уже готовые языки (что конечно предпочтительнее). Логика на в этих сценариях не делает системных вызовов, а вот логика в метамодели — может.

Ваш пример с формой можно решать двумя путями:
1. Выделить метаданные, а потом задавая и интерпретируя их, менять порядок обработки полей, правила обработки, например можно вынести регулярные выражения для валидации в метаданные, можно вынести декларативные правила валидации, которые управляют порядком проверки и условиями. Это декларативный путь, Вы применяете декларативные метаданные, можно их в JSON или XML передавать, а можно в своей специализированной грамматика.
2. И второй вариант — активные (императивные) метаданные — сценарии, например на JS, о них я говорил выше.

Но в общем случае, ни там ни другим не обойдешься, нужны и декларативные и активные метаданные.
Sign up to leave a comment.

Articles