Hai affrontato un problema comune:cercare di utilizzare qualcosa di statico (database con struttura predefinita) per qualcosa di dinamico (un mucchio di singoli set di dati che hanno solo una cosa in comune:provengono da moduli). Quello che vuoi è fattibile con i database ma sarebbe molto più facile farne a meno, tuttavia dal momento che presumo che tu voglia davvero usare un database per questo, ecco cosa farei:
- Hai un
document
(o questionario ) che contiene piùquestions
. Entrambi sono abbastanza generici e richiedono tabelle proprie, proprio come hai fatto finora. - Ogni domanda ha un
type
che definisce che tipo di domanda si tratta (multiple select, freeform, select one... ) e ovviamente la domanda ha ancheoptions
. Quindi sono due tavoli in più. Il ragionamento qui è che il disaccoppiamento di questi dalla domanda effettiva consente l'esistenza di un certo livello di astrazione e le tue domande saranno comunque alquanto semplici anche se forse troppo lunghe.
Quindi, ogni documento ha 1..n di domande, ogni domanda ha 1 tipo e 1..n opzioni. Saltando un po', ecco a cosa sto pensando con le tabelle di collegamento ecc.
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
Questo tipo di design consente diverse cose:
- Le domande stesse sono riutilizzabili, molto utili se stai creando un generico "rispondi a queste x domande casuali da un pool di y domande ".
- Nuovi tipi possono essere aggiunti facilmente senza interrompere quelli esistenti.
- Puoi sempre navigare all'interno della struttura abbastanza facilmente, ad esempio "Qual era il nome del documento per questa risposta a domanda singola che ho? " o "quante persone hanno risposto in modo errato a questa domanda?"
- Poiché i tipi sono separati, puoi creare un'interfaccia utente (web) che rifletta facilmente lo stato nel database, meglio ancora, se il tipo cambia potresti non dover nemmeno toccare il codice dell'interfaccia utente.
- Poiché ogni possibile opzione per una domanda è la propria riga in
QuestionOptions
tabella, puoi ottenere il valore effettivo molto facilmente.
Il problema ovvio con questo è che richiede un accoppiamento abbastanza rigoroso tra le tabelle per l'integrità e sarà una seccatura farlo funzionare correttamente all'inizio. Anche da value
in QuestionOptions
è varchar, devi essere in grado di analizzare molto le cose e potresti anche voler introdurre un altro campo per i suggerimenti di conversione.
Spero che questo ti aiuti anche se non saresti affatto d'accordo con la mia soluzione.