Задался вопросом как бы так запроектировать структуру БД, чтобы её для всех задач использовать.
За основу взял такую задачу - справочник по радиоэлектронным компонентам.
Суть его такова, есть типы компонентов (конденсаторы, резисторы, ...). У каждого типа есть обязательный набор характеристик (для конденсаторв: Напряжение и ёмкость, для резисторов: сопротивление и мощьность). Также у каждого типа есть специфические характеристики, но необязательные (для конденсаторов: ТКЕ-температурный коэфициент ёмкости, для резисторов: ТКС - температурный коэфициент сопротивления).
Плюс к этому у каждого компонента может быть уникальная, важная характеристика.
Разумеется у каждого элемента есть марка (наименование)
Дерево элементов можно представить так:
|
|-конденсаторы
| |- К50-35 16В 100мкФ ±20% (ёмкость-100мкФ, напряжение-16В, допуск по ёмкости ±20%)
| |- К50-35 35В 2200мкФ ±20% (ёмкость-2200мкФ, напряжение-35В, допуск по ёмкости ±20%)
|-Резисторы
| |- С2-32-1 100 ±5% (сопротивление-100 Ом, мощьность 1Вт, допуск по сопротивлению ±5%)
| |- С2-29-0,5 1к ±0,5% (сопротивление-1 кОм, мощьность 0,5Вт, допуск по сопротивлению ±0,5%)
Немного усовершенствовал диалог настройки патрахов БД:
Что почитать не подскажу.
Пока в голову пришла мысль: для каждого типа данных использовать отдельную таблицу, с полем value нужного типа.
Когда-то на прежней работе подобная задача ставилась...Тоже создавали универсальную структуру БД. было там порядка 15 служебных таблиц (для описания таблиц, полей, типов, связей...). На всё это вешалась куча триггеров, которые собственно и "раскручивали" всё это дело. Например, была таблица document, описывающая все "обычные" таблицы. Запись в неё приводило к созданию таблицы. Была таблица document_fields - тоже назначение понятно. Были таблицы для описания типов полей, которые делились на базовые и ссылочные. И самый верх всего этого - универсальное редактирование документов. Сценарий должен был сам подгружать данные о полях документа и создавать нужные элементы управления. Причём отредактировать можно было всё, что угодно - даже записи в documents и documents_fields, что приводило к соответствующим действиям...А ещё выстраивалась древовидная структура документов (не на внешних ключах, а "вообще")
Через некоторое время я задался задачей написания своего варинанта, на sql-server (а то было на postgres), но что-то отвлёкся и отошёл...
Скрипт прилагаю, глянь, если очень будет интересно)))
Есть таблички:
db_tables(id, name, description),
db_tables_fields(id, id_db_table, name, id_type, default_value, description)
types(id, name, description).
При вставке в db_tables должна создаваться таблица с именем name (триггер на insert)
Таблица types должна быть заполнена интересующими типами.
При вставке в db_tables_fields в таблицу по ссылке id_db_table должно вставляться поле, тип которого определяется по ссылке id_type.
Как-то так.
А если создавать для каждого типа свою таблицу, то как будет выглядеть логика? Например, в таблице int_values будут хранится ВСЕ целочисленные значения в БД? А как определить, к какой сущности они относятся? К какой конкретно записи? Как будут выглядеть запросы?
Раз уж проектируется универсальная структура ДБ, то ограничений должно быть как можно меньше. Нужно, чтобы было некое "ядро", через которое уже "раскручивается" нужная предметная область. Хотим, чтобы в ДБ были разные типы - значит их может быть сколько угодно. А ещё они могут быть ссылками. Применительно к конкретной предметной области "клиент" не должен видеть никакой кухни. Он говорит, допустим "хочу, чтобы в базе была такая-то сущность с такими-то сущностями" - "ядро" должно подготовить таблицу с нужными полями.
Думаю, полезно будет почитать, например, о том, как функционируют базы данных CMS.
может хватит велик изобретать, а стоит посмотреть системные таблицы MS SQL....
Не бывает "универсальной структуры БД".
Иначе её бы уже давно разработали и все бы использовали.
Всё очень сильно зависит от класса задач, структуры данных, методов их использования, от типа движка.
"Универсальная" для одного из классов задач будет очень плохо подходить для другого.
Хорошее решение для версионника будет ложить блокировочник и наоборот.
Хотя можно написать некоторое количество шаблонов для сходных задач и приёмов программирования, а потом их использовать в похожих задачах.
В любом случае нужно иметь в виду, что реляционный подход в ОО напрямую не переводится, и хорошо спроектированная реляционная база довольно криво выглядит с точки зрения объектного дизайна и наоборот.
Сходного везде очень много. Но и различий тоже хватает.
Для некоторого круга задач вполне подойдёт просто текстовый файл или файловая система с файликами вместо RDBMS, для некоторых лучше OODB, для каких-то XML-DB...
И на всех них можно просто нарисовать и домашнюю бухгалтерию, и какой-нибудь сбор данных и каталог радиодеталей.
И "универсальные" схемы данных можно изобразить.
А всё же не легче какую-нибудь систему ORM использовать, раз уж очень хочется такой прям объектности с реляционной СУБД?
я на заре своей рабочей карьеры разрабатывала крупные базы и по собственному опыту знаю, что всегда хочется спроектировать супер-пупер базу на все случаи жизни, но на деле такая база нафиг не нужна, ибо:
-она будет громоздка, сложна и неудобна в использовании
-она будет тормозить совершенно дико и её нельзя будет использовать для более-менее приличных объёмов данных
-наступит день, когда все её супер-пупер свойства окажутся недостаточны для совершенно очевидного мелкого пустяка и придётся её дорабатывать
кстати, в инете полно чумовых проектов на подобную тему. копай в сторону веб-программирования, там всегда пытаются сделать бэк-офис для создания произвольных документов. у меня даже были ссылки на более-менее удачные решения, но сейчас они канули в лету, ибо я базами уже давно не занималась.
вообще, для таких вещей лучше базу брать с триггерами, пользовательскими функциями и прочей автоматизационной лабудой. это обычно монстры типа Oracle, MS SQL или Sybase. вообще, без таких свойств база как бы и не база, а просто набор файлов данных с интерфейсом.
кстати, как тут выше заметили, служебные таблицы MySQL - отличный пример довольно гибкого решения для многих задач. конечно, не универсальный, но весьма практичный. а с объектами, и тем более программной логикой будете трахаться долго и нудно и мало чего сделаете. всё, что существует в данной области, обычно либо громоздко и неуклюже, либо убого и никому нафиг не нужно на практике.
вот если взять системы сбора и обработки данных, то там мало что меняется по своей сути, меняются пожалуй только названия объектов и их свойств. Если ограничится такой областью применения, то наверно можно получить и резвую систему.
Как уже сказали это будет медленнее чем база написанная под конкретную задачу.
На мой взгляд, это похоже на создание нового языка программирования. Я бы шел снизу вверх, и мне это видится примерно так:
Базовые типы.
Строка, целое, десятичное, дата, время и.т.д. Представлены таблицами вида [ID, Value].
Ссылки (указатели)
Каждая таблица имеет свой TableID. Ссылка это пара TableID и ID записи в соответствующей таблице. Ссылка может ссылаться на все типы, включая массивы и объекты.
Если нужны ссылки на ссылки, то к базовым классам добавляем таблицу ссылок вида [ID, RefTableID, RefID] .
Массивы
В таблице массивов хранятся не значения, а ссылки на значения, поэтому в массиве можно хранить элементы разных типов. Вид таблицы: [ID, ArrayID, Index, RefTableID, RefID]. ArrayId - поле по которому можно отделить элементы одного массива от другого.
Объекты или коллекции
Наборы именованных ссылок, вид [ID, ObjectID, Key, RefTableID, RefID] . В твоем случае конденсаторы и резисторы представляются именно ими. Ссылка может ссылаться на что угодно даже на другой объект, т.е. мы можем хранить деревья, строить списки и.т.п.
Классы
Если хотим иметь более строгие объекты, то создаем еще таблицу в которой перечислены поля объектов, их типы и опции полей. Что-то типа [ID, ObjectID, FieldType(храниться TableID), Required ...].
Работать напрямую с таблицами нельзя, нужно писать хранимки. Для поддержания целостности, нужны триггеры.
IMHO получается довольно универсальная и расширяемая система, но по поводу скорости работы вопрос.
Это не готовый проект, а только мои размышления.
А смысл создавать новый язык, если уже есть готовые, нужно только реализовать тот самый мэпинг... систему соотношения, во)
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)