![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Хранение справочников в одной таблице. Предлагаю обсудить идею. [D7, MSSQL]
AndrewK © (2005-09-05 17:23:00)Доброго времени суток!
Есть идея некоторые справочники, хранить в унифицированном виде.
В таком виде предлагается хранить всякие классификаторы, перечислимые справочники и т.д. Например, справочник цветов, рабочих мест, географии, профессий, складов и т.д.
Для этого создается такая структура:
Create table [CollectionType]
(
[ID] Integer Identity NOT NULL,
[Parent_ID] Integer NULL,
[Name] Varchar(50) NOT NULL,
[Alias] Varchar(50) NULL,
[IsGroup] Tinyint Default 0 NOT NULL,
Primary Key ([ID])
)
go
Create table [Collection]
(
[ID] Integer Identity NOT NULL,
[CollectionType_ID] Integer NOT NULL,
[Value] Varchar(250) NULL,
Primary Key ([ID])
)
go
Create table [ParamPlacement]
(
[Collection_ID] Integer NOT NULL,
[Note] Varchar(250) NULL,
Primary Key ([Collection_ID])
)
go
Create table [ParamWorkPlace]
(
[Collection_ID] Integer NOT NULL,
[Code] Varchar(10) NULL,
[Status] Tinyint NULL,
Primary Key ([Collection_ID])
)
go
Create Index [ixCollectionType] ON [Collection] ([CollectionType_ID] )
go
Alter table [CollectionType] add foreign key([Parent_ID]) references [CollectionType] ([ID]) on update no action on delete no action
go
Alter table [Collection] add foreign key([CollectionType_ID]) references [CollectionType] ([ID]) on update no action on delete no action
go
Alter table [ParamPlacement] add foreign key([Collection_ID]) references [Collection] ([ID]) on update no action on delete no action
go
Alter table [ParamWorkPlace] add foreign key([Collection_ID]) references [Collection] ([ID]) on update no action on delete no action
go
В таблице CollectionType вводим типы справочников, например, "Склады", "Цвета", "Профессии". Также там можно группировать справочники для удобства.
В таблице Collection храняться сами значения справочников (для теста там указан тип varchar, но можно поставить sql_variant)
Если справочник должен содержать не только списоные данные, а еще и дополнительные, например комментарий, персональный код или еще что-нибудь, то создается дополнительная таблица с префиксом Param, связанная с соответствующим ID таблицы Collection. Для контроля целостности можно навешать триггеров, но сейчас это опустим.
Что мы получим хорошего:
1. Единая философия создания справочников в системе.
2. Можем создать конструктор, который облегчит создание новых справочников
3. Можем создать почти универсальный модуль для управления справочниками (универсальный - если конструктор форм вынести за пределы приложения, но это уже украшательства)
4. Уменьшим число таблиц
5. Хранить все будем в одном месте, не предется рыться среди сотни таблиц в поисках одной маленькой, но очень нужной.
6. Можем навесить на таблицы сервисы контроля, логирования и т.д., которые не надо будет копировать, если будет нужен новый справочник.
7. Что-то еще есть хорошее, интуиция подсказывает....
Что получим плохого:
1. Наверное получим тормозов на больших объемах
2. Может получим проблемы с работой большого числа пользователей
3. Можем получить путаницу в данных, если начнем бездумно работать с таблицами
4. Может еще чего-нибудь получим нехорошего, не придумал пока.
Идея, думаю, не нова. Оцените, пожалуйста, ее на качество, хорошая или нет, где, по вашему, могут быть проблемы и стоит ли заморачиваться по разработке в данном направлении или лучше все по старому: один справочник - одна таблица + три-пять процедур.
С уважением.
Андрей Жук (2005-09-06 19:08:00) [1]А я в одном из проектов не только справочники, а и оперативные данные в одной таблице соединил. + таблица типов (иерархические). Для недостающих аттрибутов - блоб-поле для xml
Sergey_Masloff (2005-09-06 18:55:00) [2]Alexander Panov © (06.09.05 18:53) [38]
>Эти варианты имеют право на жизнь во многих случаях.
Золотые слова ;-)
Alexander Panov (2005-09-06 18:53:00) [3]Sergey_Masloff (06.09.05 18:48) [37]
Если справочников сотни, в любом случае будет очень тяжело ориентироваться в большом объеме.
Все же имена таблиц, которые говорят сами за себя - удобнее.
Плюсы и минусы, конечно, каждый для себя увидит-)
Эти варианты имеют право на жизнь во многих случаях.
Sergey_Masloff (2005-09-06 18:48:00) [4]Alexander Panov © (06.09.05 18:44) [36]
Скажу так - на нашей реальной базе (20 млн. записей) при принятой по умолчанию степени соответствия я ни разу более 3 не встречал. Причем в 99% нужное было первым ;-) Хошь верь хошь не верь... Да правда удобно.
Alexander Panov (2005-09-06 18:44:00) [5]Sergey_Masloff (06.09.05 18:35) [35]
Кроме того сделан эвристический поиск который наведет тебя даже если задать 'ВАЛЮТЫ СПРАВ' 'СЛОВАРЬ ВАЛЮТЫ' 'ВАЛЮТЫ КЛАССИФИКАТОР'
А если этот поиск выдаст тысячи полторы совпадений?
Sergey_Masloff (2005-09-06 18:35:00) [6]Alexander Panov © (06.09.05 18:24) [32]
>А как ты запоминаешь идентификатор справочника валюты? В голове >держишь?
Зачем? Ведь корень справочника так и называется - справочник валют. Кроме того сделан эвристический поиск который наведет тебя даже если задать 'ВАЛЮТЫ СПРАВ' 'СЛОВАРЬ ВАЛЮТЫ' 'ВАЛЮТЫ КЛАССИФИКАТОР' и многое другое. Кроме того так как это дерево то руками раскрыть пару уровней не проблема.
Кстати вся запись через единый интерфейс, руками в базу нет нужды писать ни разработчику ни программисту.
Понимаешь, если Диасофт сделали по ...ски это не значит что все подобного рода сделано так же. Диасофт я видел там действительно мрак.
Кстати тут с форума пару человек нашу систему видели изнутрей - ужаса и особых трудностей во въезжании не было, может если не лень будет подтвердят.
Sergey_Masloff (2005-09-06 18:29:00) [7]Alexander Panov © (06.09.05 18:19) [31]
>А если в ней находятся классификаторы к 20-ти справочникам?
Да хоть к 20 тысячам (как у нас и есть)
Документы - это не справочная таблица.
Твоя задача надуманная - в ней нет никакого подвоха. При чем тут 20 видов документов? Хоть 120
select d.id, c.code currcode, cl.shortname doctype, ... xN.shortname someother
from docs d, dicti c, dicti cl, dicti x2, ... dicti xN
where d.clientidn = :id
and d.currid = c.id(+)
and d.doctype = cl.id(+)
...
and d.someattr = xN.id
и все вытащили. Никаких проблем. Джойн - это как раз то что любой SQL сервер умеет делать лучше всего.
Alexander Panov (2005-09-06 18:26:00) [8]Если постоянно не заниматься разработкой, то сопровождение с нуля(вместе с изучением) подобной задачи - полный мрак.
Alexander Panov (2005-09-06 18:24:00) [9]Sergey_Masloff (06.09.05 18:12) [30]
То есть никогда не вспоминаешь - а валюты это у меня какая таблица? А типы платежей? А контрагенты? А счета? ;-)
А как ты запоминаешь идентификатор справочника валюты? В голове держишь?
То же касается и остальных.
Для составления олюбого запроса тебе нужно сначала вспомнить(найти) идентификаторы, классификаторы нужных тебе понятий, толтько потом увязывать их в запросе.
Alexander Panov (2005-09-06 18:19:00) [10]Sergey_Masloff (06.09.05 18:12) [30]
А тут все самодокументировано - человек смотрит одну таблицу и в ней находит все.
Хорошо, если это одна таблица. А если в ней находятся классификаторы к 20-ти справочникам?
Допустим, есть таблица проводок, документов, клиентов.
В этих таблицах находятся исключительно ссылки на эту громадную таблицу в числовом виде.
Пусть будет 20 видов документов, 5 тысяч клиентов, и 1000000 различных классификаторов в справочной таблице.
Есть задание - найти документы клиента "Рога и копыта", и получить полностью всю информацию по документу.
Предложи путь решения задачи?
Sergey_Masloff (2005-09-06 18:12:00) [11]Alexander Panov © (06.09.05 18:06) [28]
Варум????
Могу уверить - ничего подобного. Более того, имхо НАМНОГО проще так как джойнишь всегда с одной и той же таблицей. То есть никогда не вспоминаешь - а валюты это у меня какая таблица? А типы платежей? А контрагенты? А счета? ;-) И попробуй расскажи это новичку.
А тут все самодокументировано - человек смотрит одну таблицу и в ней находит все. Так что надумано это все. С любым подходом можно сделать г а можно конфетку и если конкретно у тебя не получилось конфетки таким способом не надо говорить что это невозможно (обратное тоже верно). То есть я уверен что в системе 1 справочник-1 таблица тоже можно сделать нормально, более того я делал когда-то и с автогенерацией форм для редактирования и просмотра и так далее. Но потом решил что удобнее не так (для меня). Подход вроде оправдывается ;-)
Sergey_Masloff (2005-09-06 18:07:00) [12]Alexander Panov © (06.09.05 18:03) [26]
Какой такой? ;-)) Из поста неясно
Alexander Panov (2005-09-06 18:06:00) [13]AndrewK (06.09.05 17:19) [25]
Прямо бальзам на душу. :)
Как раз после того, как система поработает, обрастет доп. функциями.
Через месяц-два после того, как позанимаешься другими делами, составление SQL-запроса для получения данных будет представлять собой весьма нетривиальную задачу.
Alexander Panov (2005-09-06 18:04:00) [14]Сопровождение и добавление функционала - еще более огромная.
Alexander Panov (2005-09-06 18:03:00) [15]Расширение(программирование) такой системы - полная ж.
Достаточно посмотреть, как организовано в Диасофт5НТ, чтобы навсегда забыть такой подход.
AndrewK (2005-09-06 17:19:00) [16]> Sergey_Masloff (06.09.05 17:07) [24]
> >А какое количество записей в справочниках храниться у Вас
> Порядка 20 млн.
> Система большая пользователей очень много. Тормозов нет.
По-моему, это более чем достаточно для уничтожения всех сомнений о тормозах.
> В отдельные (они не отдельные на самом деле) таблицы выносятся только те что не влазят по ширине в общую шапку. Но и для них шапки в этой единой таблице есть. То есть любую справочную информацию вытаскиваем ВСЕГДА из одной таблицы но иногда приходится джойнить ее с расширением. Хотя даже при наличии расширения джойн часто не нужен.
Вот это я и хотел услышать. Прямо бальзам на душу. :)
Sergey_Masloff (2005-09-06 17:07:00) [17]AndrewK (06.09.05 16:36) [19]
>А какое количество записей в справочниках храниться у Вас
Порядка 20 млн.
Система большая пользователей очень много. Тормозов нет.
В отдельные (они не отдельные на самом деле) таблицы выносятся только те что не влазят по ширине в общую шапку. Но и для них шапки в этой единой таблице есть. То есть любую справочную информацию вытаскиваем ВСЕГДА из одной таблицы но иногда приходится джойнить ее с расширением. Хотя даже при наличии расширения джойн часто не нужен.
AndrewK (2005-09-06 16:59:00) [18]> Name - это чтобы пользователь знал, что он знал, что правит.
Эк я завернул... :-o
Правильно так:
Name - это чтобы пользователь знал, что правит.
AndrewK (2005-09-06 16:58:00) [19]> Sergey13 © (06.09.05 16:42) [20]
> Что за алиас? Name из CollectionType?
Alias - это системное имя справочника. Задается один раз при его создании. В примере я его не стал указывать, так как не считаю это поле таким уж значимым. Как вариант можно распечатать ID справочников и ими пользоваться. Просто с Alias более читабельно. Name - это человеко читаемое название справочника. Так как сам справочник унифицирован, то и редактор тоже один. Name - это чтобы пользователь знал, что он знал, что правит.
> А если придет грамотей и исправит американский "Color" на английский "Colour"? Где будут твои запросы?
Процедуры, настроенные на справочник Color перестанут работать. То же случиться, если я переименую таблицу в Enterprice Manager.
Sergey13 (2005-09-06 16:43:00) [20]Сори
>Name из CollectionType?
читать
Alias из CollectionType?