Você enfrentou um problema comum:Tentar usar algo estático (banco de dados com estrutura predefinida) para algo dinâmico (bando de conjuntos de dados individuais que têm apenas uma coisa em comum:eles vêm de formulários). O que você quer é possível com bancos de dados, mas seria significativamente mais fácil ficar sem, no entanto, como eu suponho que você realmente queira usar um banco de dados para isso, aqui está o que eu faria:
- Você tem um
document
(ou questionário ) que contém váriasquestions
. Ambos são genéricos o suficiente e exigem suas próprias tabelas, assim como você fez até agora. - Cada pergunta tem um
type
que define que tipo de pergunta é (seleção múltipla, forma livre, selecione uma... ) e claro que a pergunta também temoptions
. Então são mais duas mesas. O raciocínio aqui é que dissociar isso da questão real permite que exista um certo nível de abstração e suas consultas ainda serão um pouco simples, embora possivelmente loooooong.
Assim, cada documento tem 1..n de perguntas, cada pergunta tem 1 tipo e 1..n opções. Pulando um pouco, aqui está o que estou pensando com tabelas de links etc.
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
Esse tipo de design permite várias coisas:
- As próprias perguntas são reutilizáveis, muito úteis se você estiver fazendo um genérico "responda a essas x perguntas aleatórias de um conjunto de y perguntas ".
- Novos tipos podem ser adicionados facilmente sem quebrar os existentes.
- Você sempre pode navegar pela estrutura com bastante facilidade, por exemplo "Qual era o nome do documento para esta única resposta de pergunta que eu tenho? " ou "quantas pessoas responderam incorretamente a esta pergunta?"
- Como os tipos são separados, você pode criar uma interface do usuário (web) que reflita o estado no banco de dados com facilidade - melhor ainda, se o tipo mudar, talvez você nem precise tocar no código da interface do usuário. >
- Como cada opção possível para uma pergunta é sua própria linha no
QuestionOptions
tabela, você pode obter o valor real com muita facilidade.
O problema óbvio com isso é que requer um acoplamento bastante estrito entre as tabelas para integridade e será difícil começar a funcionar corretamente no início. Também desde
value
em QuestionOptions
é varchar, você precisa ser capaz de analisar muitas coisas e pode até querer introduzir outro campo para dicas de conversão. Espero que isso ajude, mesmo que você não concorde com a minha solução.