Дизайн на схема за това, когато потребителите могат да дефинират полета

Поздрави стекери,

Опитвам се да измисля най-добрата схема на база данни за приложение, което позволява на потребителите да създават проучвания и да ги представят на обществеността. Има куп "стандартни" демографски полета, които повечето проучвания (но не всички) ще включват, като собствено име, фамилия и т.н. И разбира се потребителите могат да създават неограничен брой "персонализирани" въпроси.

Първото нещо, за което се сетих е нещо подобно:

Survey
  ID
  SurveyName

SurveyQuestions
  SurveyID
  Question

Responses
  SurveyID
  SubmitTime

ResponseAnswers
  SurveyID
  Question
  Answer

Но това ще е гадно всеки път, когато искам да изведа данни. И изглежда опасно близо до Ефекта на вътрешната платформа

Подобрение би било да включа колкото се може повече полета, за които мога да се сетя предварително в таблицата с отговори:

Responses
  SurveyID
  SubmitTime
  FirstName
  LastName
  Birthdate
  [...]

Тогава поне заявките за данни от тези общи колони са ясни и мога да попитам, да речем, средната възраст на всеки, който някога е отговарял на анкета, където е посочил рождената си дата.

Но изглежда, че това ще усложни малко кода. Сега, за да видя кои въпроси се задават в анкета, трябва да проверя кои общи полета за отговор са активирани (като използвам, предполагам, битово поле в Анкета) И какво има в таблицата SurveyQuestions. И трябва да се тревожа за специални случаи, като например ако някой се опита да създаде „персонализиран“ въпрос, който дублира „общ“ въпрос в таблицата с отговори.

Това ли е най-доброто, което мога да направя? Изпускам ли нещо?


person Eli    schedule 09.01.2009    source източник
comment
Мога ли да предложа да промените заглавието на вашия въпрос на Коя е най-добрата схема на база данни за система за проучване?   -  person William Brendel    schedule 09.01.2009


Отговори (4)


Вашата първа схема е по-добрият избор от двете. На този етап не трябва да се тревожите за проблеми с производителността. Тревожи се да направиш добър, гъвкав, разширяем дизайн. Има всякакви трикове, които можете да направите по-късно, за да кеширате данни и да правите заявки по-бързо. Използването на по-малко гъвкава схема на база данни, за да се реши проблем с производителността, който може дори да не се материализира, е лошо решение.

Освен това, много (може би повечето) резултати от проучването се преглеждат само периодично и от малък брой хора (организатори на събития, администратори и т.н.), така че няма постоянно да правите заявки в базата данни за всички резултати. И дори да беше, представянето ще бъде наред. Вероятно така или иначе щяхте да пагинирате резултатите по някакъв начин.

Първата схема е много по-гъвкава. По подразбиране можете да включите въпроси като име и адрес, но за анонимни проучвания можете просто да не ги създавате. Ако създателят на анкетата иска да види само отговорите на всички на три от петстотин въпроса, това е наистина проста SQL заявка. Можете да настроите каскадно изтриване за автоматично изтриване на отговори и въпроси при изтриване на анкета. Генерирането на статистика също ще бъде много по-лесно с тази схема.

Ето една леко модифицирана версия на предоставената от вас схема. Предполагам, че можете да разберете кои типове данни къде отиват :-)

    surveys
      survey_id (index)
      title

    questions
      question_id (index, auto increment)
      survey_id (link to surveys->survey_id)
      question

    responses
      response_id (index, auto increment)
      survey_id (link to surveys->survey_id)
      submit_time

    answers
      answer_id (index, auto increment)
      question_id (link to questions-question_id)
      answer
person William Brendel    schedule 09.01.2009

Бих ви предложил винаги да приемате нормализиран подход към схемата на вашата база данни и след това да решите дали трябва да създадете решение от съображения за производителност. Преждевременната оптимизация може да бъде опасна. Преждевременната денормализация на базата данни може да бъде катастрофална!

Бих предложил да се придържате към оригиналната схема и по-късно, ако е необходимо, да създадете отчетна таблица, която е денормализирана версия на вашата нормализирана схема.

person Andrew Hare    schedule 09.01.2009

Една промяна, която може или не може да помогне за опростяване на нещата, е да не свързвате ResponseAnswers обратно към SurveyID. По-скоро създайте ID за отговор и за въпрос и оставете вашата таблица ResponseAnswers да съдържа полетата ResponseID, QuestionID, Answer. Въпреки че това би изисквало запазване на уникални идентификатори за всяка единица, това би помогнало нещата да останат малко по-нормализирани. Не е необходимо отговорите на отговорите да се свързват с анкетата, на която отговарят, само с конкретния въпрос, на който отговарят, и информацията за отговора, с която са свързани.

person Bill    schedule 09.01.2009

Създадох система за проучвания на клиенти на предишната си работа и излязох със схема, много подобна на тази, която имате. Използва се за изпращане на анкети (на хартия) и таблично представяне на отговорите.

Няколко дребни разлики:

  • Проучванията НЕ бяха анонимни и това беше много ясно посочено в отпечатаните формуляри. Това също означава, че демографските данни във вашия пример са били известни предварително.

  • Имаше набор от въпроси, които бяха прикачени към анкетите, така че един въпрос можеше да се използва в множество анкети и да се анализира независимо от анкетата, в която се появи.

  • Работата с различни видове въпроси стана интересна – имахме скала 1-3 (напр. По-лошо/Същото/По-добро), скала 1-5 (Много лошо, Лошо, Добре, Добро, Много добро), Да/Не и коментари .

    Имаше специален код за обработка на коментарите, но другите типове въпроси се обработваха общо чрез таблица с типове въпроси и друга таблица с валидни отговори за всеки тип.

За да улесните заявките, вероятно бихте могли да създадете функция, която да връща отговора въз основа на ID на анкета и ID на въпрос.

person Dave    schedule 09.01.2009
comment
Добри точки. Да, пропуснах да се занимавам с различни видове въпроси, за да съсредоточа публикацията си, но ще трябва да се справя и с това плюс поддръжка за дефинирани от потребителя правила за валидиране. - person Eli; 09.01.2009