Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ SQL. Базы данных. _ Проектирование универсальной структуры БД

Автор: Litkevich Yuriy 20.11.2009, 13:51

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

Дерево элементов можно представить так:

|
|-конденсаторы
|    |- К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%)


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

Где-то так должен выглядеть процесс настройки заготовки БД:


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

Может кто-нибудь подсказать, где про такие вещи почитать?

Автор: Litkevich Yuriy 20.11.2009, 14:55

Немного усовершенствовал диалог настройки патрахов БД:



А пользователь должен при этом получить примерно такой диалог:

Автор: BRE 20.11.2009, 15:23

Что почитать не подскажу.

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

Автор: Litkevich Yuriy 20.11.2009, 15:51

Цитата(BRE @ 20.11.2009, 18:23) *
для каждого типа данных использовать отдельную таблицу, с полем value нужного типа.
я пока дальше этого тоже не ушёл.
Если кол-во типов ограничить:
* целое
* дробное
* текст
то три таблицы надо, вполне нормально

Автор: Elfinit 30.11.2009, 23:54

Когда-то на прежней работе подобная задача ставилась...Тоже создавали универсальную структуру БД. было там порядка 15 служебных таблиц (для описания таблиц, полей, типов, связей...). На всё это вешалась куча триггеров, которые собственно и "раскручивали" всё это дело. Например, была таблица document, описывающая все "обычные" таблицы. Запись в неё приводило к созданию таблицы. Была таблица document_fields - тоже назначение понятно. Были таблицы для описания типов полей, которые делились на базовые и ссылочные. И самый верх всего этого - универсальное редактирование документов. Сценарий должен был сам подгружать данные о полях документа и создавать нужные элементы управления. Причём отредактировать можно было всё, что угодно - даже записи в documents и documents_fields, что приводило к соответствующим действиям...А ещё выстраивалась древовидная структура документов (не на внешних ключах, а "вообще")
Через некоторое время я задался задачей написания своего варинанта, на sql-server (а то было на postgres), но что-то отвлёкся и отошёл...
Скрипт прилагаю, глянь, если очень будет интересно)))


 common_db.zip ( 7.31 килобайт ) : 217
 

Автор: Elfinit 1.12.2009, 9:54

Цитата(Litkevich Yuriy @ 20.11.2009, 15:51) *
для каждого типа данных использовать отдельную таблицу

Зачем?

Цитата(Litkevich Yuriy @ 20.11.2009, 15:51) *
Если кол-во типов ограничить:
...
то три таблицы надо, вполне нормально

Это не универсальное решение. Зачем себя ограничивать?)

Автор: Litkevich Yuriy 1.12.2009, 11:51

Цитата(Elfinit @ 1.12.2009, 12:54) *
Зачем?
например, перечисленные выше типы данных, как хранить в одной таблице?

Автор: Elfinit 1.12.2009, 21:40

Есть таблички:
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.

Автор: Litkevich Yuriy 1.12.2009, 21:52

Цитата(Elfinit @ 2.12.2009, 0:40) *
При вставке в db_tables должна создаваться таблица с именем name (триггер на insert)
в FireBird нельзя создавать объекты БД внутри тригеров и хранимых процедур.

Цитата(Elfinit @ 2.12.2009, 0:40) *
Например, в таблице int_values будут хранится ВСЕ целочисленные значения в БД?
ну я пока на этом остановился

Цитата(Elfinit @ 2.12.2009, 0:40) *
А как определить, к какой сущности они относятся? К какой конкретно записи?
иметь доп поле с идентификатором записи

для меня большей проблемой является не ограничение числа типов, трёх за глаза и зауши.
Для меня является проблемой "Сущность и её свойства" где-то сзади чешется, что свойства тоже являются сущностью, тогда где их держать?

Автор: trdm 2.12.2009, 1:43

может хватит велик изобретать, а стоит посмотреть системные таблицы MS SQL....
:)

Автор: Tonal 2.12.2009, 11:24

Не бывает "универсальной структуры БД".
Иначе её бы уже давно разработали и все бы использовали. :)

Всё очень сильно зависит от класса задач, структуры данных, методов их использования, от типа движка.
"Универсальная" для одного из классов задач будет очень плохо подходить для другого.
Хорошее решение для версионника будет ложить блокировочник и наоборот. :)

Хотя можно написать некоторое количество шаблонов для сходных задач и приёмов программирования, а потом их использовать в похожих задачах. :)

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

Автор: Litkevich Yuriy 2.12.2009, 11:37

Цитата(Tonal @ 2.12.2009, 14:24) *
что реляционный подход в ОО напрямую не переводится, и хорошо спроектированная реляционная база довольно криво выглядит с точки зрения объектного дизайна и наоборот.
да про это я уже довольно много прочитал. Собственно в книге Хелен Бри написано, что хорошая модель данных не значит хорошая структура БД, если пытаться эту модель один к одному перенести в БД.

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

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

Автор: Tonal 2.12.2009, 11:50

Сходного везде очень много. Но и различий тоже хватает. :)
Для некоторого круга задач вполне подойдёт просто текстовый файл или файловая система с файликами вместо RDBMS, для некоторых лучше OODB, для каких-то XML-DB...

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

Автор: Elfinit 2.12.2009, 19:58

Цитата(trdm @ 2.12.2009, 1:43) *
может хватит велик изобретать, а стоит посмотреть системные таблицы MS SQL....

Практика показала, что их недостаточно) Да, есть там, например [dbo].[sysobjects] (вроде). Ну и? Там вперемешку таблицы, процедуры, функции?
А как программную логику сделать для создаваемых таблиц? Точнее, чтобы она АВТОМАТИЧЕСКИ генерировалась? Как установить довольно сложные взаимодействия между сущностями? Писать триггеры к системным таблицам? Там получится куча условий и вообще тёмный лес....
В общем, аргумент такой: работа с системными таблицами не универсальна и не гибка.


Цитата(Litkevich Yuriy @ 1.12.2009, 21:52) *
Для меня является проблемой "Сущность и её свойства" где-то сзади чешется, что свойства тоже являются сущностью, тогда где их держать?

Первое, что пишло на ум - это аналогия reference-type и value-type. Т.е. свойство может быть ссылкой на сущность. А может и has is к сущности.

Вообще, советую почитать про ER-модели, это первое, с чего начинают проектирование БД. В UML можно заглянуть. После этого многое понятно станет. Очевидно, что раз хочется универсальную БД, то надо абстрагироваться от предметной области.

Цитата(Litkevich Yuriy @ 1.12.2009, 21:52) *
в FireBird

З.Ы. Firebird - реляционная, или объектно-реляционная СУБД? Леньгуглить)

Автор: Litkevich Yuriy 2.12.2009, 20:44

Цитата(Elfinit @ 2.12.2009, 22:58) *
Firebird - реляционная
такая

Автор: Novak 3.12.2009, 13:35

А всё же не легче какую-нибудь систему ORM использовать, раз уж очень хочется такой прям объектности с реляционной СУБД?

Автор: Litkevich Yuriy 3.12.2009, 15:26

Цитата(Novak @ 3.12.2009, 16:35) *
систему ORM использовать
я смутно представляю, что это такое

Автор: Iron Bug 3.12.2009, 15:32

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

кстати, в инете полно чумовых проектов на подобную тему. копай в сторону веб-программирования, там всегда пытаются сделать бэк-офис для создания произвольных документов. у меня даже были ссылки на более-менее удачные решения, но сейчас они канули в лету, ибо я базами уже давно не занималась.
вообще, для таких вещей лучше базу брать с триггерами, пользовательскими функциями и прочей автоматизационной лабудой. это обычно монстры типа Oracle, MS SQL или Sybase. вообще, без таких свойств база как бы и не база, а просто набор файлов данных с интерфейсом.
кстати, как тут выше заметили, служебные таблицы MySQL - отличный пример довольно гибкого решения для многих задач. конечно, не универсальный, но весьма практичный. а с объектами, и тем более программной логикой будете трахаться долго и нудно и мало чего сделаете. всё, что существует в данной области, обычно либо громоздко и неуклюже, либо убого и никому нафиг не нужно на практике.

Автор: Novak 3.12.2009, 16:32

Цитата(Litkevich Yuriy @ 3.12.2009, 15:26) *
я смутно представляю, что это такое

По сути это такой сторонний промежуточный слой между тобой и базой данных. В Django таким образом очень удобно работать с моделями - ты описываешь данные, а не то, как они должны храниться.
По сути да, это медленней, менее эффективно. Но при не очень больших объёмах данных вполне оправдано.

Автор: Litkevich Yuriy 3.12.2009, 16:59

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

Автор: Sokoloff 4.12.2009, 1:41

Как уже сказали это будет медленнее чем база написанная под конкретную задачу.
На мой взгляд, это похоже на создание нового языка программирования. Я бы шел снизу вверх, и мне это видится примерно так:

Базовые типы.
Строка, целое, десятичное, дата, время и.т.д. Представлены таблицами вида [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 получается довольно универсальная и расширяемая система, но по поводу скорости работы вопрос.
Это не готовый проект, а только мои размышления.

Автор: Novak 4.12.2009, 11:48

А смысл создавать новый язык, если уже есть готовые, нужно только реализовать тот самый мэпинг... систему соотношения, во)

Автор: Sokoloff 4.12.2009, 12:54

Цитата(Novak @ 4.12.2009, 11:48) *
А смысл создавать новый язык, если уже есть готовые, нужно только реализовать тот самый мэпинг... систему соотношения, во)


Сразу оговорюсь, я не являюсь профессионалом в данной области.

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

То на что я глядел из ORM (глядел, не работал, сейчас даже названий не вспомню) реализовывали немного другой подход. В процессе проектирования описывались структуры данных, потом запускался скрипт создания базы для необходимых объектов. Юрию нужно добавление новых атрибутов в рантайме. Если есть готовые ORM реализующие это, подскажите Юрию, скорее всего для C++.

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

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)