Comments 51
Если я правильно понял мысль, то это просто 2 разные нормальные формы таблиц.
Да, разумеется. Просто хочется услышать плюсы и минусы каждой из реализаций. Одни из самых явных — на добавление нового типа объекта в первом варианте будет портачено гораздо меньше времени, чем во втором (быстрая расширяемость).
UFO just landed and posted this here
Из коммерческих CMS такую реализацию выбрали UMI.CMS и Netcat, поэтому, изучив эти системы, мне и пришло в голову посоветоваться с Хабрасообществом. Спасибо за совет ;-).
Пред-рас-судки.
«Уровень требуемой квалификации» — вот именно. Это не ущербная попытка. Это не каждому быдлокодеру доступный вариант.
«Уровень требуемой квалификации» — вот именно. Это не ущербная попытка. Это не каждому быдлокодеру доступный вариант.
Если мы говорим о реляционных БД, то первый вариант имеет очень ограниченное применение. Да это универсально, но за универсальность надо платить, в данном случае, производительностью.
Если хочется объектную бд, то нужно пользоваться хотя бы ORDMS (объектно-реляционная) PostgreSQL...
В первом случае вы, как мне кажется, описываете так называемую EAV модель, или модель Тенцера. Недостатки очевидны - медленные INSERT, UPDATE, DELETE. Необходимость реализовывать самому проверку связей между объектами, интерфейс по управлению свойствами объектов, типов, и т.д. Плюсов тоже не мало, это почти(!) универсально, но не так производительно, как во втором случае. Мне кажется тут надо смотреть, для чего конкретно разрабатывается БД.
при разработке конкретного проекта конечно предпочтительней второй вариант, реализация проще и скорость выше. первый больше подходит при разработке универсальной платформы
А затем появятся объекты, которые как и туда и сюда подходят. Грубо говоря были Новости и Статьи, к ним добавили Анонсы - куда их - в отдельную таблицу?
Затем придут теги - и все сущности придется как-то перевязывать между собой, то есть к каждой таблице сущностей добавится еще таблица-связка с тегами.
Затем придут теги - и все сущности придется как-то перевязывать между собой, то есть к каждой таблице сущностей добавится еще таблица-связка с тегами.
Теги, комментарии — это настолько обобщенные сущности, что их спокойно можно хранить каждый в одной таблице, привязывая к объектам с помощью идентификатора (objectID) и типа (objectType).
Про «Новости, Статьи, Анонсы» — детальная схожесть этих трех объектов взывает к хранению их в одной таблице, с разными типами (поле type).
Про «Новости, Статьи, Анонсы» — детальная схожесть этих трех объектов взывает к хранению их в одной таблице, с разными типами (поле type).
А как быть со внешними ключами в этой схеме?
А что если внешним ключом назначить связку objectType и objectID?
Не очень понял как это можно сделать. Колонка должна ссылаться на колонку в другой таблице. Можно ли ссылаться сразу на несколько таблиц?
Не, не может, насколько я знаю. Потому единственный вариант, что могу предложить: таблицу ObjectUniqueIds и ссылки на нее из всех таблиц, к которым можно привязать теги и комменты. Тогда внешний ключ реализуется в два этапа: ObjectID -> ObjectUniqueID -> Comments|Tags. Но тут, конечно придется генерить UniqueID вручную (триггером).
Кстати, msSQL есть такая штука как UID - тип данных такой. Он ваще уникальный.
Кстати, msSQL есть такая штука как UID - тип данных такой. Он ваще уникальный.
Первый вариант похож на систему, расчитанную под будующую (считаем неизвестную на момент разработки) сильную кастомизацию. Один из таких известнейших продуктов - 1С.
http://www.oracle.com/global/ru/oramag/august2004/russia_gen_abramov.htm
В статье дано описание Remedy, это не суть важно, легко можно подставить туда и "пункт 1".
http://www.oracle.com/global/ru/oramag/august2004/russia_gen_abramov.htm
В статье дано описание Remedy, это не суть важно, легко можно подставить туда и "пункт 1".
Я знаю третий. Как только кармы хватит напишу статью по этому поводу.
Поднял карму. Можете написать в личный блог.
Спасибо :) Попробую до футбола выделить время на статью. Моя(?) идея как раз для социальных подходит лучше всего.
Сорри за оффтоп, но: а хабракармаэффект уже не работает? Раньше за просьбы кармы жестоко расплачивались.
ОФФТОП: Я думаю, если человек просит на дело - статью по интересующей тебя теме, то ничего плохого в этом не вижу. От этого только все выиграют.
Прошу прощения, я тут новенький :)
Статья готова http://rvk.habrahabr.ru/blog/45259.html
Надеюсь достойная плата за карму.
Статья готова http://rvk.habrahabr.ru/blog/45259.html
Надеюсь достойная плата за карму.
1 вариант использутся при гибкой по своей природе структуре таблиц
За второй вариант вас зато никогда не побьют последующие разработчики
За второй вариант вас зато никогда не побьют последующие разработчики
Можно предложить еще "третий" вариант: настройщик описывает сущности и связи в какой-либо нотации, а программа затем "умно" генерирует объекты БД (таблицы, хранимки...)по второму варианту.
Выйдет очередной конструктор а-ля 1С :)
Выйдет очередной конструктор а-ля 1С :)
Все это объединено дисциплиной ORM (Object-Relational Mapping) и хорошо описано на разных ресурсах. Способов представления объектов немного больше чем 2. Вот, например, есть такая статья: http://www.agiledata.org/essays/mappingObjects.html
в ActiveRecord (RoR) эти свзянности уже давно сформулированы (также как и в LIMB-фреймворке, предлагающем свой вариант ActiveRecord)
has_one - связанность один объект к одному
belongs_to - то же самое, но с foreign_key
has_many - множество к одному
has_many_and_belongs_to - один к множеству через дополнительную мета-таблицу
has_one - связанность один объект к одному
belongs_to - то же самое, но с foreign_key
has_many - множество к одному
has_many_and_belongs_to - один к множеству через дополнительную мета-таблицу
UFO just landed and posted this here
Для хранение объектов с похожей структурой годится наследование, в котором основная таблица
содержит общие для всех атрибуты, такие как id, pub_date, mod_date, author_id ...., а
остальные таблица наследуя ее, добавляют свои атрибуты. При этом можно использовать поиск как
по отдельным таблицам, так и по всем (спрашивая мастер таблицу). В PostgreSQL это реализуется
весьма просто. Есть еще способ в PostgreSQL - иметь одну таблицу с общими атрибутами, а всю
специфику вынести в отдельное поле типа перлового хэша.
содержит общие для всех атрибуты, такие как id, pub_date, mod_date, author_id ...., а
остальные таблица наследуя ее, добавляют свои атрибуты. При этом можно использовать поиск как
по отдельным таблицам, так и по всем (спрашивая мастер таблицу). В PostgreSQL это реализуется
весьма просто. Есть еще способ в PostgreSQL - иметь одну таблицу с общими атрибутами, а всю
специфику вынести в отдельное поле типа перлового хэша.
Да, структура получается очень гибкой, но есть проблема в обработке. Комфортно с ней можно работать только из Perl-а. Когда система развивается, возникает большая потребность в интеграции с другими компонентами, которые могут быть написаны на других языках. И вот там распарсивание хеша может стать проблемой, приходится лепить костыли: парсить руками, либо писать специальные хранимые процедуры для вытаскивания определенных полей хеша.
Я бы предложил хранение в виде XML (благо постгрес нормально с ним работает).
Плюсы:
+ очень гибко - в поле можно записать все, что угодно: хоть сложное дерево настроек, хоть массив объектов
+ без проблем обрабатывается приложением на любом языке, а так же самой базой
+ удобная возможность поиска с помощью xpath-запросов
+ для ускорения такого поиска можно построить индекс по конкретным xpath-запросам. В зависимости от особенностей задачи можно использовать разные индексы - впрочем про них вы больше меня расскажите :)
Минусы:
- производительность
Я бы предложил хранение в виде XML (благо постгрес нормально с ним работает).
Плюсы:
+ очень гибко - в поле можно записать все, что угодно: хоть сложное дерево настроек, хоть массив объектов
+ без проблем обрабатывается приложением на любом языке, а так же самой базой
+ удобная возможность поиска с помощью xpath-запросов
+ для ускорения такого поиска можно построить индекс по конкретным xpath-запросам. В зависимости от особенностей задачи можно использовать разные индексы - впрочем про них вы больше меня расскажите :)
Минусы:
- производительность
Почему только из перла ? В PostgreSQL можно работать c SQL, если пользовать наше расширение hstore (http://www.sai.msu.su/~megera/wiki/Hstor…)
Для хранения объектов с множеством (от одного до сотни и далее) свойств еще выгодно использовать мета-таблицы.
Например есть сущность User, есть сущности UserGroup, UserAccess etc. В основной табллице хранится главная информация - login, password, created_at и т.д., и связи с правами и группой. В мета-таблице - UserMeta - хранятся свойства объекта в виде ключ-значение: что то вроде (id, user_id, property, value).
Тогда при выборке свойств объекта будут два запроса - первым этамом выборка информации из главной таблицы и связанных таблиц; вторым этапом выборка мета-свойств объекта.
Кто еще применяет такую же архитектуру? Знаю что в WordPress используется такая же идея (свзянность между posts и posts_meta).
Например есть сущность User, есть сущности UserGroup, UserAccess etc. В основной табллице хранится главная информация - login, password, created_at и т.д., и связи с правами и группой. В мета-таблице - UserMeta - хранятся свойства объекта в виде ключ-значение: что то вроде (id, user_id, property, value).
Тогда при выборке свойств объекта будут два запроса - первым этамом выборка информации из главной таблицы и связанных таблиц; вторым этапом выборка мета-свойств объекта.
Кто еще применяет такую же архитектуру? Знаю что в WordPress используется такая же идея (свзянность между posts и posts_meta).
* первым этамом - первым этапом
поднимите карму, напишу подробнее как такая же схема используется в classifieds движках (движках объявлений)
поднимите карму, напишу подробнее как такая же схема используется в classifieds движках (движках объявлений)
Если очень много изменяющихся свойств(меняется струткура ) - выделяют ядро сущности, которое хранится в обычных полях. Все поля, которые могут меняться, загоняют в поле xml. эти свойства вторичны и запросы по ним не выполняются или выполняются очень редко, все активные действия выполняяются над полями ядра. Раньше использовалось clob и udf, которые парсили это поле, с появлением xml все делается гораздо проще и быстрее, стандартными средствами.
Наследование в рсубд практически не используется. Нафига, база должна хранить данные, остальным займется приложение.
Наследование в рсубд практически не используется. Нафига, база должна хранить данные, остальным займется приложение.
> Раньше использовалось clob и udf, которые парсили это поле, с появлением xml все делается гораздо проще и быстрее, стандартными средствами.
Ну xml в крайнем случае можно закешировать.
> Наследование в рсубд практически не используется. Нафига, база должна хранить данные, остальным займется приложение.
Согласен, база должна хранить данные, а не модель (модель строится на основе этих данных + поведении). Маппингом данных и сущностей занимается ORM.
Насчет выделения какого-то ядра у сущности - несколько туманная идея... можете привести примеры?
Каковы плюсы от проектировать БД на основе частоты изменения полей?
Ну xml в крайнем случае можно закешировать.
> Наследование в рсубд практически не используется. Нафига, база должна хранить данные, остальным займется приложение.
Согласен, база должна хранить данные, а не модель (модель строится на основе этих данных + поведении). Маппингом данных и сущностей занимается ORM.
Насчет выделения какого-то ядра у сущности - несколько туманная идея... можете привести примеры?
Каковы плюсы от проектировать БД на основе частоты изменения полей?
>Насчет выделения какого-то ядра у сущности - несколько туманная идея... можете >привести примеры?
>Каковы плюсы от проектировать БД на основе частоты изменения полей?
Я приводил решение для случая когда у сущности много изменяющихся полей. Например у кредитной истории могут появляться дополнительные атрибуты необходимые для каких-то скоринговых целей. Основные атрибуты КИ( субъект, документы, адрес, данные бюро) уже определены и не меняются. Просто все поля, которые планируются в будущем видоизменть или добавлять, добавляются в структуру xml. В результате никаких мета-таблиц не надо создавать, определяете схему документа и вперед. Так удобнее. Во первых у старые версии сущности не будут обрастать не используемыми полями, функционалом. И контроль версий естественно лучше. Программа может спокойно парсить сущность по старой xsd, а новые записи по новой. И все это хранится в одной таблице, где количество колонок фикисровано. По произовдительности я думаю даже выигрыш будет против многослойных джойнов.
>Каковы плюсы от проектировать БД на основе частоты изменения полей?
Я приводил решение для случая когда у сущности много изменяющихся полей. Например у кредитной истории могут появляться дополнительные атрибуты необходимые для каких-то скоринговых целей. Основные атрибуты КИ( субъект, документы, адрес, данные бюро) уже определены и не меняются. Просто все поля, которые планируются в будущем видоизменть или добавлять, добавляются в структуру xml. В результате никаких мета-таблиц не надо создавать, определяете схему документа и вперед. Так удобнее. Во первых у старые версии сущности не будут обрастать не используемыми полями, функционалом. И контроль версий естественно лучше. Программа может спокойно парсить сущность по старой xsd, а новые записи по новой. И все это хранится в одной таблице, где количество колонок фикисровано. По произовдительности я думаю даже выигрыш будет против многослойных джойнов.
UFO just landed and posted this here
Работали над проектом автоматизации финансового блока компании.
Архитектором выбрал первый вариант, в связи с планировавшейся большой универсальностью и подключением большого числа модулей других подразделений компании.
В итоге все это вылилось в огромный геморрой при работе с данными и пришлось все упрощать и отпиливать напильником в сторону второго варианта.
Архитектором выбрал первый вариант, в связи с планировавшейся большой универсальностью и подключением большого числа модулей других подразделений компании.
В итоге все это вылилось в огромный геморрой при работе с данными и пришлось все упрощать и отпиливать напильником в сторону второго варианта.
UFO just landed and posted this here
Хочу прокомментировать первый вариант - сейчас на работе с ним приходиться иметь дело...
Описание данной схемы неполно... В нашем случае ObjectsFields является не отдельной таблицей, а целым набором таблиц, для разных типов данных своя таблица. Т.е. существуют таблицы ObjectFieldsVarchar, ObjectFieldsDate, ObjectFieldsBlob и так далее... Понятно, что можно сделать одну таблицу ObjectsFields, в которой будут поля всех типов, но в итоге это совсем не намного изменит ситуацию - работать с этой пачкой сложно.
Присоединюсь ко всем здесь высказывавшимся - работать с этой пачкой говна очень сложно. Либо полностью через хранимые процедуры (которые возвращают тебе строку с полями, которые ты запросил), либо приходится делать УЖАСНЫЕ извращения на клиенте. В частности ужасной ужастностью здесь является известная N+1 проблема, из-за которой динамическая lazy-линковка практически невозможно.
Описание данной схемы неполно... В нашем случае ObjectsFields является не отдельной таблицей, а целым набором таблиц, для разных типов данных своя таблица. Т.е. существуют таблицы ObjectFieldsVarchar, ObjectFieldsDate, ObjectFieldsBlob и так далее... Понятно, что можно сделать одну таблицу ObjectsFields, в которой будут поля всех типов, но в итоге это совсем не намного изменит ситуацию - работать с этой пачкой сложно.
Присоединюсь ко всем здесь высказывавшимся - работать с этой пачкой говна очень сложно. Либо полностью через хранимые процедуры (которые возвращают тебе строку с полями, которые ты запросил), либо приходится делать УЖАСНЫЕ извращения на клиенте. В частности ужасной ужастностью здесь является известная N+1 проблема, из-за которой динамическая lazy-линковка практически невозможно.
1. Это архитектурный паттерн БД EAV (Entity-Attributes-Values).
2. Это архитектурный паттерн БД Entities and External Domains (название моё, модель по-умолчанию для большинства учебных и малых схем).
Есть ещё:
3. Core Entities & Hiers (Ключевые сущности и наследники, очень мне нравится в последнее время).
4. DW (Facts & Dimensions) — классика аналитических систем.
5. Регистры — хорошее решение для учётных систем.
Кое-какие детали есть здесь: http://DatabaseDesignPatterns.org/index.…
2. Это архитектурный паттерн БД Entities and External Domains (название моё, модель по-умолчанию для большинства учебных и малых схем).
Есть ещё:
3. Core Entities & Hiers (Ключевые сущности и наследники, очень мне нравится в последнее время).
4. DW (Facts & Dimensions) — классика аналитических систем.
5. Регистры — хорошее решение для учётных систем.
Кое-какие детали есть здесь: http://DatabaseDesignPatterns.org/index.…
первый вариант удобно использовать для мелочей, типа «Просмотры», «Рейтинг».
Sign up to leave a comment.
Варианты проектирования БД