5 Stimmen

Schemaentwurf für den Fall, dass Benutzer Felder definieren können

Grüße an die Stacker,

Ich versuche, das beste Datenbankschema für eine Anwendung zu finden, mit der Benutzer Umfragen erstellen und sie der Öffentlichkeit präsentieren können. Es gibt eine Reihe "standardmäßiger" demografischer Felder, die in den meisten Umfragen (aber nicht in allen) enthalten sein werden, wie Vorname, Nachname usw. Und natürlich können die Benutzer eine unbegrenzte Anzahl von "benutzerdefinierten" Fragen erstellen.

Das erste, woran ich dachte, war so etwas wie das hier:

Survey
  ID
  SurveyName

SurveyQuestions
  SurveyID
  Question

Responses
  SurveyID
  SubmitTime

ResponseAnswers
  SurveyID
  Question
  Answer

Aber das wird jedes Mal nerven, wenn ich Daten abfragen will. Und es scheint gefährlich nahe an Innerer Plattformeffekt

Eine Verbesserung wäre es, so viele Felder wie möglich im Voraus in die Antworttabelle aufzunehmen:

Responses
  SurveyID
  SubmitTime
  FirstName
  LastName
  Birthdate
  [...]

Dann ist zumindest die Abfrage von Daten aus diesen gemeinsamen Spalten einfach, und ich kann z. B. das Durchschnittsalter aller Personen abfragen, die jemals an einer Umfrage teilgenommen haben, bei der sie ihr Geburtsdatum angegeben haben.

Aber es scheint, dass dies den Code etwas verkomplizieren wird. Um zu sehen, welche Fragen in einer Umfrage gestellt werden, muss ich jetzt prüfen, welche allgemeinen Antwortfelder aktiviert sind (ich schätze, mit einem Bitfeld in Survey) UND was in der Tabelle SurveyQuestions steht. Und ich muss mich um Sonderfälle kümmern, z. B. wenn jemand versucht, eine "benutzerdefinierte" Frage zu erstellen, die eine "allgemeine" Frage in der Tabelle "Antworten" dupliziert.

Ist das das Beste, was ich tun kann? Übersehe ich etwas?

5voto

William Brendel Punkte 30822

Ihr erstes Schema ist die bessere Wahl von beiden. Zu diesem Zeitpunkt sollten Sie sich keine Gedanken über Leistungsprobleme machen. Kümmern Sie sich lieber um einen guten, flexiblen und erweiterbaren Entwurf. Es gibt alle möglichen Tricks, die Sie später anwenden können, um Daten zwischenzuspeichern und Abfragen schneller zu machen. Ein weniger flexibles Datenbankschema zu verwenden, um ein Leistungsproblem zu lösen, das vielleicht gar nicht auftritt, ist eine schlechte Entscheidung.

Außerdem werden viele (vielleicht sogar die meisten) Umfrageergebnisse nur in regelmäßigen Abständen und nur von einer kleinen Anzahl von Personen (Veranstaltungsorganisatoren, Administratoren usw.) eingesehen, so dass Sie nicht ständig die Datenbank nach allen Ergebnissen abfragen müssen. Und selbst wenn Sie das täten, wäre die Leistung in Ordnung. Wahrscheinlich würden Sie die Ergebnisse ohnehin irgendwie paginieren.

Das erste Schema ist viel flexibler. Sie können standardmäßig Fragen wie Name und Adresse einbeziehen, aber für anonyme Umfragen können Sie diese einfach nicht erstellen. Wenn der Ersteller der Umfrage nur die Antworten aller Teilnehmer auf drei von fünfhundert Fragen sehen möchte, ist das eine ganz einfache SQL-Abfrage. Sie könnten eine kaskadierende Löschung einrichten, um Beantwortungen und Fragen automatisch zu löschen, wenn eine Umfrage gelöscht wird. Auch die Erstellung von Statistiken wird mit diesem Schema viel einfacher.

Hier ist eine leicht geänderte Version des von Ihnen bereitgestellten Schemas. Ich nehme an, Sie können herausfinden, welche Datentypen wohin gehören :-)

    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

1voto

Andrew Hare Punkte 332190

Ich würde vorschlagen, dass Sie immer einen normalisierten Ansatz für Ihr Datenbankschema wählen und dann später entscheiden, ob Sie eine Lösung aus Leistungsgründen erstellen müssen. Eine verfrühte Optimierung kann gefährlich sein. Eine verfrühte De-Normalisierung der Datenbank kann katastrophal sein!

Ich würde vorschlagen, dass Sie das ursprüngliche Schema beibehalten und später, falls erforderlich, eine Berichtstabelle erstellen, die eine de-normalisierte Version Ihres normalisierten Schemas ist.

1voto

Bill Punkte 413

Eine Änderung, die zur Vereinfachung beitragen kann, wäre, die ResponseAnswers nicht mehr mit der SurveyID zu verknüpfen. Erstellen Sie stattdessen eine ID pro Beantwortung und pro Frage und lassen Sie Ihre Tabelle ResponseAnswers die Felder ResponseID, QuestionID, Answer enthalten. Dies würde zwar eindeutige Bezeichner für jede Einheit erfordern, aber es würde helfen, die Dinge ein wenig mehr zu normalisieren. Die Beantwortungen müssen nicht mit der Umfrage verknüpft werden, die sie beantwortet haben, sondern nur mit der spezifischen Frage, die sie beantworten, und den Beantwortungsinformationen, die sie zugeordnet sind.

0voto

Dave Punkte 7718

Bei meiner früheren Tätigkeit habe ich ein System für Kundenbefragungen entwickelt und ein ähnliches Schema wie das Ihre. Es diente dazu, Umfragen (auf Papier) zu versenden und die Antworten tabellarisch zu erfassen.

Es gibt ein paar kleine Unterschiede:

  • Erhebungen wurden NICHT anonym und dies wurde in den gedruckten Formularen sehr deutlich gemacht. Es bedeutete auch, dass die demografischen Daten in Ihrem Beispiel im Voraus bekannt waren.

  • Es gab einen Pool von Fragen, die an die Umfragen angehängt waren, so dass eine Frage in mehreren Umfragen verwendet und unabhängig von der Umfrage, in der sie gestellt wurde, analysiert werden konnte.

  • Der Umgang mit verschiedenen Arten von Fragen wurde interessant - wir hatten eine Skala von 1 bis 3 (z. B. Schlecht/Gleich/Besser), eine Skala von 1 bis 5 (Sehr schlecht, schlecht, OK, gut, sehr gut), Ja/Nein und Kommentare.

    Für die Kommentare gab es einen speziellen Code, aber die anderen Fragetypen wurden generisch behandelt, indem eine Tabelle mit den Fragetypen und eine weitere Tabelle mit den gültigen Antworten für jeden Typ erstellt wurde.

Um die Abfrage zu erleichtern, könnten Sie wahrscheinlich eine Funktion erstellen, die die Antwort auf der Grundlage einer Umfrage-ID und einer Frage-ID zurückgibt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X