Схема расширяемой базы данных - как хранить значения расширяемого атрибута - PullRequest
2 голосов
/ 21 июля 2011

Мы используем SQL Server 2008, и одним из требований является наличие расширяемых пользовательских атрибутов для сущностей, определенных для системы. Например, у нас может быть объект «Доктор», мы хотим, чтобы администраторы системы могли определять дополнительные атрибуты, которые обычно отсутствуют в системе. Эти атрибуты, скорее всего, понадобятся как критерии запроса, связывающие родительские или объединяющие таблицы.

Будут таблицы, которые определяют атрибуты (имя, описание, тип) и т. Д., Но мой вопрос касается хранения фактических значений данных.

Я не администратор баз данных (просто программист, притворяющийся таковым), но моей первой мыслью было сохранить их в одном общем столбце как

nvarchar(450)

Это охватывало бы большинство основных типов и по-прежнему позволяло бы индексировать, но я думал, что столкнусь с множеством проблем с типами конверсий (преобразование в даты, числа и т. Д.), А также с необычными проблемами с запросами, поскольку все это nvarchar .

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

ColNVarCharData
nvarchar(450) 

ColBitData
bit

ColIntData
int

.. И т. Д.

Когда пользователь определял расширяемый атрибут, он выбирал тип данных, а затем мы сохраняли значение атрибута в этом столбце для этого типа. Например, если они выбрали int, значение данных будет сохранено в ColIntData, а два других столбца будут нулевыми в этом примере.

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

Я склоняюсь к использованию этого, но удивляюсь, есть ли у кого-нибудь еще какие-либо предложения. Я кратко рассмотрел тип данных XML, но «схема» могла меняться довольно часто, поэтому я подумал, что это лучше подходит.

Ответы [ 2 ]

2 голосов
/ 21 июля 2011

Вот только несколько SO вопросов / ответов, относящихся к теме.

0 голосов
/ 21 июля 2011

Исходя из ссылки, которую @gbn прислал мне в комментариях, я думаю, что это эффективный ответ (взято из ссылки WIKI):

Значение

Приведение всех значений в строкикак в приведенном выше примере с данными EAV, получается простая, но не масштабируемая структура: взаимные преобразования постоянных типов данных требуются, если кто-то хочет что-то сделать со значениями, и индекс в столбце значений таблицы EAVпо сути бесполезно.Кроме того, неудобно хранить большие двоичные данные, такие как изображения, в закодированной форме Base64 в той же таблице, что и маленькие целые числа или строки.Поэтому большие системы используют отдельные таблицы EAV для каждого типа данных (включая большие двоичные объекты, «BLOBS»), а метаданные для данного атрибута идентифицируют таблицу EAV, в которой будут храниться ее данные.Этот подход на самом деле довольно эффективен, потому что скромное количество метаданных атрибутов для данного класса или формы, с которыми пользователь выбирает работать, может быть легко кэшировано в памяти.Однако, это требует перемещения данных из одной таблицы в другую, если тип данных атрибута изменяется.(Это случается не часто, но при определении метаданных могут быть допущены ошибки, как и при проектировании схемы базы данных.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...