Хранение данных из форм без создания сотен таблиц: ASP.NET и SQL Server - PullRequest
2 голосов
/ 27 июля 2010

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

  1. Событие с датами, временем, менеджерами, внутренней платежной информацией и т. Д.
  2. Регистрационная запись с информацией об оплате и общей сумме, взимаемой за отправку формы
  3. Био / демографические данные и данные выпускников об 1 или более участниках (имя, адрес, степень и т. Д.)

Мы храним все вышеперечисленные данные в столбцах в таблицах, как и следовало ожидать.

Проблема заключается в «дополнительных» полях, которые нас просят заполнить формы. Может быть, это ужин, и есть вариант Veggie или Carnivore, возможно, есть жилье и есть варианты кровати или курения, или, возможно, есть дополнительный вариант транспорта. Есть тонны странных маленьких "вы можете добавить это в форму?" типы запросов, которые мы получаем.

В настоящее время мы JSONify для всех нестандартных данных и храним их в одном столбце (для каждого участника), который называется «дополнительные». Мы можем прочитать эти данные в коде, но они плохо подходят для запросов. Наш внутренний персонал хотел бы составить быстрый отчет о вегетарианских обедах, необходимых, например.

Кроме создания отдельной таблицы для каждой формы, содержащей конкретные «дополнительные» элементы данных, существуют ли другие подходы, которые могли бы облегчить мою жизнь (и отчетность)? Кто-нибудь работает в среде simialr?

Ответы [ 5 ]

3 голосов
/ 27 июля 2010

Это на самом деле одна из самых сложных задач, которую нужно эффективно решить.Консультативная группа по SQL Server для клиентов посвятила официальный документ теме, которую я настоятельно рекомендую прочитать: Рекомендации по моделированию семантических данных для повышения производительности и масштабируемости .

У вас в основном есть 3 варианта:

Каждое решение имеет взлеты и падения.Я бы сказал, что XML - это тот, который дает вам наилучший баланс мощности и гибкости, но оптимальное решение действительно зависит от множества факторов, таких как размеры наборов данных, частота, с которой создаются новые атрибуты,фактический процесс (операторы-люди), которые создают-заполняют, используют эти атрибуты и т. д., а не, по крайней мере, ваш набор навыков команды (некоторые могут лучше работать с решением EAV, другие могут лучше работать с решением XML).Если атрибуты создаются / управляются центральным органом и добавление новых атрибутов является достаточно редким событием, то разреженные столбцы могут быть лучшим ответом.

3 голосов
/ 27 июля 2010

Ну, вы могли бы также иметь следующую структуру БД:

Есть таблица для хранения пользовательских атрибутов

AttributeID
AttributeName

Иметь таблицу сопоставления между событиями и атрибутами с:

AttributeID
EventID
AttributeValue

Это означает, что вы сможете хранить пользовательскую информацию для каждого события. И вы сможете повторно использовать свои атрибуты. Вы можете включить некоторые метаданные как

AttributeType
AllowBlankValue 

к атрибуту, чтобы потом легко его обрабатывать

2 голосов
/ 27 июля 2010

Рассматривали ли вы использование XML вместо JSON? Разница: XML поддерживается (специальный тип данных) и имеет интеграцию запросов;)

0 голосов
/ 27 июля 2010

Это решение, которое мы впервые предложили на форумах ASP.NET (позже он стал Community Server), и что команда ASP.NET создала аналогичную версию в членстве ASP.NET 2.0, когда выпустила ее:

Сумки свойств на объектах вашего домена

Например:

Event.Profile () или, в вашем случае, Event.Extras ().

По сути,Свойство bag представляет собой сериализованную коллекцию данных, хранящихся в паре имя / значение в столбце (или столбцах).Членство в ASP.NET 2.0 пошло по пути сохранения имен в списке, разделенном точкой с запятой, и значений в них:

Таблица: aspnet_Profile Столбец: PropertyNames (разделенный точками с запятой и имеющий начальный индекс иконечный индекс) Столбец: PropertyValues ​​(разделенный точками с запятой и хранящий только строковое значение)

Недостатком этого подхода является то, что это все строки, и его необходимо анализировать вручную (даже если система членства делает этоэто для вас автоматически).

Недавно мой текущий метод состоит в том, что я создал методы расширения FormCollection и NameValueCollection C #, которые автоматически сериализуют коллекции в результат XML.И я храню этот XML в таблице в своем собственном столбце, связанном с этим объектом.У меня также есть расширение десериализатора C # для XElement, которое десериализует эти данные обратно в коллекцию во время выполнения.

Это дает вам возможность фактически запрашивать эти свойства в XML через SQL (хотя это может быть медленным, хотя -всегда выравнивать ваши данные только для чтения).

Последнее замечание - запросы во время выполнения: общее правило, которое мы соблюдаем, заключается в том, что если вы собираетесь запрашивать свойство объекта в обычной логике приложения, вы перемещаете егосвойство фактического столбца в таблице - и создать соответствующие индексы.Если эти данные никогда не будут запрошены напрямую (например, Linq-to-Sql или EF), оставьте их в пакете свойств XML.

Property Bags дает вам возможность расширять ваши доменные модели без необходимости изменять схему БД.

0 голосов
/ 27 июля 2010

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

больше решение для базы данных: у вас будет что-то вроде идентификатора события в вашей таблице.Вы можете связать это с таблицей n: m, связывая события с дополнительными полями.А затем сохраните данные дополнительного поля в таблице с дополнительным_поле_id, record_id (из исходной таблицы) и фактическим значением.Вероятно, создает ужасные запросы, но кажется политически корректным с точки зрения дизайна базы данных.

Я понимаю, что базы данных "NoSQL" (не только sql;), такие как couchdb, позволяют хранить произвольные поля для каждой записи, но, поскольку вы ужеSQL Server, я думаю, это не вариант.

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