Модель данных опроса - Как избежать EAV и чрезмерной денормализации? - PullRequest
8 голосов
/ 07 января 2011

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

Мой вопрос: как мне смоделировать ответы на вопросы опроса в СУРБД?Использование SQL Server обязательно.Таким образом, альтернативные системы хранения данных должны быть исключены из этого обсуждения.(Конечно, некоторые должны и будут оцениваться, но не здесь, пожалуйста.) Мне не нужно решение для всей модели данных, сейчас мне интересна только часть Ответы.

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

Некоторые предположения относительно данных, с которыми мне приходится иметь дело:

  1. Каждый опрос состоит из от 1 до n вопросников
  2. Каждый вопросник состоит из 100-2000 вопросов (пожалуйста,не обращайте внимания на то, что 2000 вопросов действительно звучат как ответы на многие вопросы ...)
  3. Вопросы могут быть разных типов: множественный выбор, свободный текст, число (например, возраст, доход, проценты, ...)
  4. В каждом опросе участвуют 10-200 стран (это не респонденты. Респонденты на самом деле люди в странах.)
  5. В зависимости от типа вопросника, на каждый вопросник отвечает 100-20 000респондентов на страну.
  6. Страна может адаптировать вопросники для опроса, то есть добавлять, удалять или редактировать вопросы
  7. Данные по одной стране собираются в отдельной базе данных в этой стране.С самого начала нет возможности для онлайн-интеграции.
  8. Данные для всех стран должны быть интегрированы позже.Это означает, например, что если страна удалила вопрос, то данные должны быть каким-то образом получены из того, что они отправили, для достижения единого дизайна во всех странах
  9. Мне придется написать программное обеспечение для интеграции и очистки,который должен работать с данными каждой страны
    1. В конце данные необходимо экспортировать в плоские файлы, по одной прямоугольной сетке на страну и вопросник.

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

  1. Эксперты в области, которые привыкли работать с плоскими файлами (в стиле электронных таблиц) для обработки и анализа данных, голосуют за денормализованную структуру с множеством таблиц и столбцов.как я описал выше (1 таблица на страну и анкету).Это звучит ужасно для меня, потому что я узнал, что широких таблиц следует избегать, будет неудобно определять, какие столбцы на самом деле находятся в таблице, при работе с ней база данных будет загромождена сотнями таблиц (или мне даже нужносоздать несколько баз данных, каждая с похожим, но немного отличающимся дизайном) и т. д.
  2. ОО-программисты голосуют за строго «нормализованный» дизайн, который фактически приведет к созданию центральной таблицы, содержащей все ответы от всехРеспонденты на все вопросы.Эта таблица должна содержать столбец типа sql_variant type или несколько столбцов ответов с различными типами для хранения ответов различных типов (множественный выбор, свободный текст и т. Д.).Первый, по сути, будет моделью EAV.Я склонен следовать за Джо Селко, который категорически не рекомендует его использовать (он называет это OTLT или «One True Lookup Table»).Последнее подразумевает, что каждая строка будет содержать пустые ячейки для неприменимых типов по дизайну.

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

Извините, что вам надоел весь этот текст, и спасибо за ваш вклад!

Ура, Alex

PS: я задавал тот же вопрос здесь: http://www.eggheadcafe.com/community/aspnet/13/10242616/survey-data-model--how-to-avoid-eav-and-excessive-denormalization.aspx

Ответы [ 4 ]

4 голосов
/ 07 января 2011

alt text Ну, imgur не работает, поэтому я опубликую фото позже.

Я думаю, что это вполне осуществимо в реляционной модели.Я построил CDM, чтобы показать, как я это сделаю.

Исходящий

Требуется 4 объекта для определения Обзора страны.Некоторые опросы родителей, страны и список вопросов.Ваши вопросы имеют внутреннюю связь, поэтому, когда одна страна «редактирует» вопрос, вы можете отслеживать как вопрос, заданный страной, так и вопрос, из которого она возникла.Другая вещь, в которой вы нуждаетесь, это сущность / таблица Возможный ответ.С каждым вопросом может быть связан список возможных ответов (множественный выбор или диапазоны и т. Д.).Эти 4 должны полностью определить «внешнюю» сторону этого.

Входящий

Сторона "INBOUND" - это всего лишь 2 новых объекта, Ответчик и ответ.Респондент прост, только демография этого человека, если вы его знаете, и здесь вы можете включить отношения обратно в страну.Каждый респондент ответил на опрос в данной стране.(Лицо может быть 1: n с ответчиком, если лицо путешествует или имеет двойное гражданство)

Ответ является основным;либо это один из вариантов, перечисленных в списке возможных ответов, либо он указан.Не увлекайтесь тем, что ответом может быть число, дата и т. Д.Либо это ФК или строка символов.

Отчетность

Отчет - это объединение всех этих ... Вы выберете страну и опрос, получите список вопросов и ответов.

Сложность ответа

Зависит от того, где вы хотите сделать свои расчеты.Если вы использовали столбец Varchar2 (4000) для предоставленных пользователем ответов, вы можете добавить атрибут к вопросу, чтобы описать тип данных ответа.Q: возраст?DT: целое число от (0 до 130).Тогда ваш интеграционный уровень может выполнить проверку вместо базы данных, которая его обеспечивает.Или вы можете иметь 4 столбца, один для числа, даты, символа и CLOB.И ваш уровень интеграции определит колонку для использования.Когда вы сообщите об этих ответах, вы просто выделите все четыре столбца с помощью Coalesce ().

Является ли это EAV, потому что есть некоторая двусмысленность для типа данных «Ответ»

Нет, это не так.

Модель EAV ломаетсяСущность в список атрибутов.например, так:

Entity     Attribute     Value
  1          Fname         Stephanie
  1          Lname         Page
  1          Age           30

, потому что вы видите, что столбец Ответ схемы Survey содержит и слова, и цифры, как в столбце Значение, как вы думаете, здесь определяется EAV.Это не.Точно так же, как если бы я добавил 3 столбца данных в эту модель, он не изменил бы его из EAV.

Я так ненавижу, когда

У меня есть люди, которые говорятмне, что запрос, который я настраиваю, должен идти "как можно быстрее".Итак, дайте мне миллиард долларов и 30 лет."Подождите, миллиард что?"«Столько, сколько», «так быстро, как» не являются требованиями.Вы можете проверить все, что вы хотите в базе данных ... создать загрузку Перед триггерами, вуаля!Валидация в изобилии.

Какой тип столбца возраста?Или колонка рождения?Зависит от того, что ваш источник данных.Некоторые старые записи могут иметь только месяц и год, или только год, или около или около года.Вы не могли иметь только числовой столбец и делать «как можно больше проверок».и NUMBER (2) может быть ЛУЧШЕ, чем просто NUMBER.Так что теперь у вас будет NUMBER (1), NUMBER (2), NUMBER ... чтобы иметь «столько, сколько».

Где, я думаю, вас сбивают с толку

Думайте об этом как о Концептуальной Модели данных, а не Физической.В этих терминах Опрос является юридическим лицом.Является ли Вопрос сущностью или просто атрибутом опроса.Если вы построили Одна таблица на PER , вы явно говорите, что Вопрос - это просто атрибут опроса, и его вертикальное хранение делает это EAV.Эта модель показывает, что Вопрос - это на самом деле другая сущность.Между Вопросами существует связь, например, «страна может редактировать вопросы».Был оригинальный вопрос и отредактирован один.На каждый вопрос есть коллекция возможных ответов.И самое главное, что это все вопросы .В EAV я называю fname, lname, bdate, age, major, заработную плату и т. Д. - все очень разные вещи, просто атрибуты.В этом случае мы не включаем название агентства, которое подготовило опрос, и дату его проведения, а также дату, когда он должен быть возвращен, и т. Д. ... как вопросы.

Позвольте мне выразить это иначе,Ты ФедексВы хотите хранить метки времени для определенных событий.Каждый раз, когда посылка въезжает или покидает объект или транспортное средство.Время на погрузку грузовика, время на выходе из грузовика и на первый объект, время на выходе из этого объекта на самолет и т. Д. Вы храните их горизонтально?Как узнать заранее количество прыжков?Если вы храните их вертикально, это автоматически делает их EAV?И если да, то почему.

Вы - метеорологическая компания, получающая временные данные со станций по всей стране.Допустим, датчики предназначены для отправки показаний, когда температура изменяется на +/- на полный градус.Если вы храните sensor_ID | timestamp | temp - это таблица чтения, это EAV?Каждое чтение не является атрибутом датчика, они сами являются сущностями, которые принадлежат к коллекции / серии.

Единственное, что вертикальное хранение ответов имеет общее с EAV, - это сложность выполнения аналитических запросов.Если вы хотите получить список всех людей, которые ответили на ИСТИННО на вопросы 5 и 10, но ЛОЖЬ на 6 и 11, было бы очень трудно, если бы они были выполнены вертикально.Может быть, поэтому вы видите это EAV.Если вы хотите сделать это, вам нужно другое хранилище.Реляционное хранение вопросов и ответов - не самая лучшая база данных отчетов.Давайте вернемся к примеру с FedEx.Это не просто сделать «транзитный» отчет о времени, когда строки расположены вертикально.

1 голос
/ 07 января 2011

Если бы я использовал SQL Server, с Express все будет в порядке, тогда я бы сделал это:

  • Таблица со списком вопросов, флажками для типа (бит), если требуется флаг (бит), правильный ответ, если существует, и т.д.
  • Таблица с перечнем стран
  • Таблица привязки стран и вопросы (некоторые страны могут не получить некоторые вопросы
  • Таблица ответов с колонками для вопрос (ы) и XML колонка для дополнительных вопросов в том числе те, которые добавлены

Если вы не разбираетесь в измельчении XML, используйте разреженные столбцы для всех дополнительных вопросов. Я не помню точно лимит на число разреженных столбцов в таблице, но я считаю, что он превышает 30 000. SQL Server внутренне сохраняет разреженные столбцы в виде XML и уничтожает их, когда выбирается столбец, и да, он может быть проиндексирован

На диаграмме ниже показана диаграмма, созданная с помощью SQL Server. столбец AL_A4 будет содержать ответ на QL_Id = 4 и имеет тип разреженный. QL_Id в таблице QuestionList не помечен как обязательный, что позволяет вам сделать колонку в AnswerList разреженной.

Поскольку страны будут добавлять вопросы, создайте таблицы QuestionListCustom, QuestiontoCountryCustom и AnswerListCustom и добавьте информацию из пользовательских вопросов.

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

alt text

1 голос
/ 07 января 2011

Звучит так, как будто вы боретесь с общей проблемой: как использовать молоток для затяжки винта.

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


Я попробовал модель EAV и отказался, потому что она была слишком сложной, и я боюсь попробовать модель с несколькими таблицами с системой реляционных баз данных. Самое простое решение, которое я нашел с реляционной базой данных: хранить каждый полный ответ как один CLOB, сериализованный в JSON или YAML (или что-то еще облегченное), в таблицу responses.

create table responses (
  id uuid primary key,
  questionnaire_id uuid references questionnaires.id,
  data text
)
0 голосов
/ 07 января 2011

Рассматривали ли вы не изобретать велосипед?Уже есть открытые приложения для опросов.Даже если они не соответствуют вашим потребностям, загрузите несколько и проверьте их модели данных.

...