Sie haben ein häufiges Problem:Sie versuchen, etwas Statisches (Datenbank mit vordefinierter Struktur) für etwas Dynamisches (Bündel einzelner Datensätze, die nur eines gemeinsam haben:Sie stammen aus Formularen) zu verwenden. Was Sie wollen, ist machbar mit Datenbanken, aber es wäre wesentlich einfacher, darauf zu verzichten, aber da ich annehme, dass Sie dafür wirklich eine Datenbank verwenden möchten, würde ich Folgendes tun:
- Sie haben ein
document
(oder Fragebogen ), die mehrerequestions
enthält . Diese beiden sind generisch genug und erfordern ihre eigenen Tabellen, so wie Sie es bisher getan haben. - Jede Frage hat einen
type
die definiert, um welche Art von Frage es sich handelt (Mehrfachauswahl, Freiform, eine auswählen... ) und natürlich hat die Frage auchoptions
. Das sind also zwei Tische mehr. Der Grund dafür ist, dass die Entkopplung dieser von der eigentlichen Frage ein gewisses Abstraktionsniveau zulässt und Ihre Abfragen immer noch etwas einfach sind, obwohl sie möglicherweise laaaaang sind.
Jedes Dokument hat also 1..n Fragen, jede Frage hat 1 Typ und 1..n Optionen. Ich überspringe ein bisschen, hier ist, woran ich mit Link-Tabellen usw. denke.
Document
bigint id
DocumentQuestions
bigint document_id
bigint question_id
Question
bigint id
varchar question
QuestionType
bigint question_id
bigint type_id
Type [pre-filled table with id:type pairs, such as 1=freeform, 2=select one etc.]
QuestionOptions
bigint id
bigint question_id
varchar description
varchar value
Answers
bigint id
bigint document_id
[etc. such as user_id]
QuestionAnswers
bigint answer_id
bigint question_id
bigint questionoptions_id
Diese Art von Design erlaubt mehrere Dinge:
- Fragen selbst sind wiederverwendbar, sehr praktisch, wenn Sie ein generisches "beantworten Sie diese x zufälligen Fragen aus einem Pool von y Fragen erstellen ".
- Neue Typen können einfach hinzugefügt werden, ohne dass bestehende beschädigt werden.
- Sie können jederzeit ganz einfach durch die Struktur navigieren, zum Beispiel "Wie hieß das Dokument für diese einzelne Frage, die ich beantwortet habe? " oder "wie viele Leute haben diese eine Frage falsch beantwortet?"
- Da die Typen getrennt sind, können Sie leicht eine (Web-)Benutzeroberfläche erstellen, die den Status in der Datenbank widerspiegelt - noch besser, wenn sich der Typ ändert, müssen Sie möglicherweise nicht einmal Ihren UI-Code anfassen.
- Da jede mögliche Option für eine Frage eine eigene Zeile in den
QuestionOptions
ist Tabelle können Sie den tatsächlichen Wert sehr einfach ermitteln.
Das offensichtliche Problem dabei ist, dass es eine ziemlich strenge Kopplung zwischen den Tabellen für die Integrität erfordert und es mühsam sein wird, beim Start richtig zu laufen. Auch seit value
in den QuestionOptions
varchar ist, müssen Sie in der Lage sein, viele Dinge zu parsen, und Sie möchten vielleicht sogar ein weiteres Feld für Konvertierungshinweise einführen.
Ich hoffe, das hilft, auch wenn Sie meiner Lösung überhaupt nicht zustimmen würden.