Дизайн базы данных для опроса [закрыто]


129

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

Я придумал два возможных решения:

  1. Создайте огромную таблицу, содержащую ответы на каждый отправленный опрос. Каждый столбец будет соответствовать ответу из опроса. т.е. SurveyID, Ответ1, Ответ2, Ответ3

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

  2. Еще я подумал о создании таблицы вопросов и таблицы ответов. Таблица вопросов будет содержать все вопросы для анкеты. Таблица ответов будет содержать отдельные ответы из опроса, каждая строка которых связана с вопросом.

    Простой пример:

    tblSurvey : SurveyID

    tblQuestion : QuestionID, SurveyID , QuestionType, Вопрос

    tblAnswer : AnswerID, Идентификатор_пользователь , QuestionID , Ответить

    tblUser : UserID , UserName

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

Буду признателен за любые идеи и предложения.


Насколько велико "довольно много"? Дайте оценку, мы говорим о миллионе или миллионе?
Хорхе Кордова

1
Серверы SQL на самом деле предназначены для работы с «тоннами» данных. У вас не должно возникнуть особых проблем с работой по схеме, о которой вы говорили.
Крис

Ответы:


123

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

- В одном опросе может быть много вопросов; один вопрос можно (повторно) использовать во многих опросах.
- Один (заранее сделанный) ответ может быть предложен на многие вопросы. На один вопрос может быть предложено множество ответов. В разных опросах на вопрос могут быть разные ответы. Ответы могут быть предложены на разные вопросы в разных опросах. По умолчанию есть ответ «Другой», если человек выбирает другой, его ответ записывается в Answer.OtherText.
- Один человек может участвовать во многих опросах, один человек может ответить на конкретный вопрос в опросе только один раз.

survey_model_02


1
какой инструмент вы использовали для создания схемы базы данных?
AndHeiberg 02

Использую Altova UModel. Это быстро, предлагает широкий выбор структур моделирования и сохраняет практически все форматы. Хотя стоит.
obimod

9
Вы также можете использовать draw.io. Это бесплатно без регистрации и простое в использовании.
usr4896260 02

3
Почему у нас есть Survey_Question_Answerи Answer? Разве Answerнедостаточно?
Абубакар Ахмад

1
Думаю Answer, хватит, Survery_question_answerизбыточно
Бэтмен

63

Мой дизайн показан ниже.

Последний скрипт создания находится на https://gist.github.com/durrantm/1e618164fd4acf91e372.

Скрипт и файл mysql workbench.mwb также доступны по адресу
https://github.com/durrantm/survey. введите описание изображения здесь


Привет, мне нравится твой дизайн. Есть ли образцы данных (дампы) для таблиц? Будет очень признателен
Emeka Mbah

Привет! Прежде всего спасибо за вашу работу, это здорово! Может быть, вы учли иерахи в одном из ваших шаблонов? Пользователь обычно предоставляет информацию о своем лидере, а эти лидеры имеют информацию о своих лидерах и так далее. А пользователи работают в разных разделах (HR, Production), и они тоже могут иметь иерархию. Таким образом, во время отчетности часто бывает необходимо различать эти уровни организации.
ruedi

@michael: Это действительно полезно. у вас есть ссылки / ссылки на github для Java с использованием Spring?
Сагар Панда

Я все еще пытаюсь выяснить, в чем разница между option_groupsи option_choicesи каков вариант использования.
PHPnoob

@PHPnoob Я думаю, что, как следует из названия, просто группирует параметры. Так что, если вы можете, например, оценивать от 1 до 5, то option_groupsдолжны позволить вам именно это, если я правильно понимаю.
displayname

18

Определенно вариант №2, также я думаю, что у вас может быть недосмотр в текущей схеме, вам может понадобиться другая таблица:

+-----------+
| tblSurvey |
|-----------|
| SurveyId  |
+-----------+

+--------------+
| tblQuestion  |
|--------------|
| QuestionID   |
| SurveyID     |
| QuestionType |
| Question     |
+--------------+

+--------------+
| tblAnswer    |
|--------------|
| AnswerID     |
| QuestionID   |
| Answer       |
+--------------+

+------------------+
| tblUsersAnswer   |
|------------------|
| UserAnswerID     |
| AnswerID         |
| UserID           |
| Response         |
+------------------+

+-----------+
| tblUser   |
|-----------|
| UserID    |
| UserName  |
+-----------+

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

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


Привет, у меня вопрос. Разве SurveyId не должен присутствовать в таблице ответов или хотя бы отметка времени, соответствующая времени управления версиями опроса? Если вы вставили вопрос в свой исходный опрос, идентификаторы вопросов изменились бы, и ответы стали бы неидентифицируемыми. Или, если это избыточно, не могли бы вы объяснить, как?
Shubham

3

Как правило, изменение схемы на основе чего-либо, что пользователь может изменить (например, добавление вопроса в опрос), следует считать довольно неприятным запахом. Бывают случаи, когда это может быть уместно, особенно при работе с большими объемами данных, но знайте, во что вы ввязываетесь, прежде чем погрузиться в них. Наличие только таблицы «ответов» для каждого опроса означает, что добавление или удаление вопросов потенциально очень дорого , и очень сложно проводить аналитику независимо от вопросов.

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

  1. Создайте подробные таблицы ответов для хранения ответов на каждый вопрос, как описано в пункте 2. Эти данные обычно не запрашиваются напрямую из вашего приложения, но будут использоваться для создания сводных данных для таблиц отчетов. Вы, вероятно, также захотите реализовать какую-либо форму архивирования или удаления этих данных.
  2. Также при необходимости создайте таблицу ответов из 1. Это можно использовать всякий раз, когда пользователи хотят увидеть простую таблицу результатов.
  3. Для любой аналитики, которая должна выполняться для целей отчетности, запланируйте задания для создания дополнительных сводных данных на основе данных из 1.

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


1

Второй подход лучше всего.

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

Вот простые вещи:

  • Поместите базу данных и войдите на свой собственный диск, а не все на C по умолчанию
  • Создайте базу данных настолько большой, насколько это необходимо, чтобы у вас не было пауз во время роста базы данных

У нас были таблицы журналов в таблице SQL Server с десятками миллионов строк.


1

№ 2 выглядит нормально.

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

Возможно, вы захотите создать индекс в поле QuestionID в таблице tblAnswer.

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


0

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


1
Есть ли причина, по которой я не мог добавить комментарии в таблицу ответов?
Майкл

0

Номер 2 правильный. Используйте правильный дизайн до тех пор, пока не обнаружите проблему с производительностью. У большинства СУБД не будет проблем с узкой, но очень длинной таблицей.


0

Наличие большой таблицы ответов само по себе не является проблемой. Пока индексы и ограничения четко определены, все будет в порядке. Мне нравится ваша вторая схема.


0

При правильном индексе ваше второе решение нормализовано и подходит для традиционной системы реляционных баз данных.

Я не знаю, насколько он огромен, но он должен без проблем вместить пару миллионов ответов.


0

Вы можете сохранить всю форму как строку JSON.

Не уверен в ваших требованиях, но этот подход будет работать в некоторых обстоятельствах.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.