Design de banco de dados para uma pesquisa [fechado]

129

Preciso criar uma pesquisa em que as respostas sejam armazenadas em um banco de dados. Só estou me perguntando qual seria a melhor maneira de implementar isso no banco de dados, especificamente as tabelas necessárias. A pesquisa contém diferentes tipos de perguntas. Por exemplo: campos de texto para comentários, perguntas de múltipla escolha e possivelmente perguntas que possam conter mais de uma resposta (por exemplo, marque todas as opções aplicáveis).

Eu vim com duas soluções possíveis:

  1. Crie uma tabela gigante que contenha as respostas para cada envio de pesquisa. Cada coluna corresponderia a uma resposta da pesquisa. ie SurveyID, Answer1, Answer2, Answer3

    Não acho que seja a melhor maneira, pois há muitas perguntas nesta pesquisa e não parece muito flexível se a pesquisa for alterada.

  2. A outra coisa que pensei foi criar uma tabela de perguntas e uma tabela de respostas. A tabela de perguntas conteria todas as perguntas da pesquisa. A tabela de respostas conteria respostas individuais da pesquisa, cada linha vinculada a uma pergunta.

    Um exemplo simples:

    tblSurvey : SurveyID

    tblQuestion : QuestionID, SurveyID , QuestionType, Question

    tblAnswer : AnswerID, UserID , QuestionID , Answer

    tblUser : UserID, UserName

    Meu problema com isso é que poderia haver toneladas de respostas que tornariam a tabela de respostas bastante grande. Não tenho certeza se isso é tão bom quando se trata de desempenho.

Eu apreciaria todas as idéias e sugestões.

Michael
fonte
Quanto é "bastante grande"? Nos dê uma estimativa, estamos falando de um milhão ou de um milhão?
Jorge Córdoba
1
Na verdade, os servidores SQL são projetados para trabalhar com 'toneladas' de dados. Você não deve ter muitos problemas ao trabalhar com o esquema sobre o qual falou.
Chris

Respostas:

123

Eu acho que seu modelo nº 2 está bom, mas você pode dar uma olhada no modelo mais complexo que armazena perguntas e respostas pré-elaboradas (respostas oferecidas) e permite que sejam reutilizadas em diferentes pesquisas.

- Uma pesquisa pode ter muitas perguntas; uma pergunta pode ser (re) usada em muitas pesquisas.
- Uma resposta (pré-fabricada) pode ser oferecida para muitas perguntas. Uma pergunta pode ter muitas respostas oferecidas. Uma pergunta pode ter respostas diferentes oferecidas em pesquisas diferentes. Uma resposta pode ser oferecida a diferentes perguntas em diferentes pesquisas. Há uma resposta "Outro" padrão, se uma pessoa escolher outra, sua resposta será registrada em Answer.OtherText.
- Uma pessoa pode participar de muitas pesquisas, uma pessoa pode responder a perguntas específicas em uma pesquisa apenas uma vez.

survey_model_02

Damir Sudarevic
fonte
1
qual ferramenta você usou para criar o esquema do banco de dados?
precisa saber é o seguinte
Eu uso o Altova UModel. É rápido, oferece uma ampla seleção de estruturas de modelagem e salva em praticamente todos os formatos. Embora, custa.
19413 obimod
9
Você também pode usar o draw.io. É gratuito, sem inscrição e fácil de usar.
precisa saber é o seguinte
3
Por que temos Survey_Question_Answere Answer? Não é apenas o Answersuficiente?
Abubakar Ahmad
1
Eu acho que Answeré o suficiente, Survery_question_answeré redundante
Batman
62

Meu design é mostrado abaixo.

O script de criação mais recente está em https://gist.github.com/durrantm/1e618164fd4acf91e372

O script e o arquivo mysql workbench.mwb também estão disponíveis em
https://github.com/durrantm/survey insira a descrição da imagem aqui

Michael Durrant
fonte
Olá, eu gosto do seu design. Por favor, tem alguma amostra de dados (despejos) para as tabelas? Irá realmente apreciar
Emeka Mbah
Olá. Primeiramente, obrigado pelo seu trabalho, isso é incrível! Você considerou hierarquias em um de seus modelos, talvez? O usuário geralmente fornece informações sobre seu líder e esses líderes têm informações sobre seus líderes e assim por diante. E os usuários trabalham em seções diferentes (RH, Produção) e elas também podem ter uma hierarquia. Portanto, durante os relatórios, muitas vezes é necessário diferir entre esses níveis da organização.
Ruedi
@ Michael: Isso é realmente útil. você tem algum link de referências / github para java usando spring?
Sagar Panda
Eu ainda estou tentando descobrir o que é a diferença entre option_groupse option_choicese o que é o caso de uso.
PHPnoob 30/08/19
@PHPnoob Acho que isso, como o nome sugere, simplesmente agrupa opções. Portanto, se você pode, por exemplo, classificar entre 1 e 5, option_groupsdeve permitir exatamente isso se eu estiver acertando.
displayname
18

Definitivamente, a opção 2, também acho que você pode ter uma supervisão no esquema atual, talvez queira outra tabela:

+-----------+
| tblSurvey |
|-----------|
| SurveyId  |
+-----------+

+--------------+
| tblQuestion  |
|--------------|
| QuestionID   |
| SurveyID     |
| QuestionType |
| Question     |
+--------------+

+--------------+
| tblAnswer    |
|--------------|
| AnswerID     |
| QuestionID   |
| Answer       |
+--------------+

+------------------+
| tblUsersAnswer   |
|------------------|
| UserAnswerID     |
| AnswerID         |
| UserID           |
| Response         |
+------------------+

+-----------+
| tblUser   |
|-----------|
| UserID    |
| UserName  |
+-----------+

Cada pergunta provavelmente terá um número definido de respostas que o usuário pode selecionar; as respostas reais serão rastreadas em outra tabela.

Os bancos de dados são projetados para armazenar muitos dados, e a maioria é dimensionada muito bem. Não há necessidade real de usar uma forma normal menor , simplesmente para economizar mais espaço.

plaina
fonte
Oi, eu tenho uma pergunta. O SurveyId também não deveria estar presente na tabela de respostas ou, pelo menos, com um carimbo de data e hora correspondente ao tempo de versão da pesquisa? Se você inserisse uma pergunta em sua pesquisa original, os questionIds mudariam e as respostas se tornariam não identificáveis. Ou, se for redundante, você poderia explicar como?
Shubham
3

Como regra geral, modificar o esquema com base em algo que um usuário pode alterar (como adicionar uma pergunta a uma pesquisa) deve ser considerado bastante fedorento. Há casos em que isso pode ser apropriado, principalmente ao lidar com grandes quantidades de dados, mas saiba no que você está se metendo antes de mergulhar. Ter apenas uma tabela de "respostas" para cada pesquisa significa que adicionar ou remover perguntas é potencialmente muito caro. e é muito difícil fazer análises de maneira independente de perguntas.

Acho que sua segunda abordagem é a melhor, mas se você tiver certeza de que terá muitas preocupações com a escala, uma coisa que funcionou para mim no passado é uma abordagem híbrida:

  1. Crie tabelas de respostas detalhadas para armazenar respostas por pergunta, conforme descrito em 2. Esses dados geralmente não seriam consultados diretamente do seu aplicativo, mas seriam usados ​​para gerar dados de resumo para as tabelas de relatórios. Você provavelmente também desejaria implementar alguma forma de arquivamento ou exclusão para esses dados.
  2. Crie também a tabela de respostas a partir de 1, se necessário. Isso pode ser usado sempre que os usuários quiserem ver uma tabela simples para obter resultados.
  3. Para qualquer análise que precise ser feita para fins de relatório, programe tarefas para criar dados de resumo adicionais com base nos dados de 1.

Isso é absolutamente muito mais trabalho a ser implementado, por isso, eu realmente não recomendaria isso, a menos que você tenha certeza de que esta tabela vai se deparar com enormes preocupações de escala.

Ryan Brunner
fonte
1

A segunda abordagem é a melhor.

Se você quiser normalizá-lo ainda mais, poderá criar uma tabela para tipos de perguntas

As coisas simples a fazer são:

  • Coloque o banco de dados e faça logon em seu próprio disco, nem todos em C como padrão
  • Crie o banco de dados tão grande quanto necessário, para que você não tenha pausas enquanto o banco de dados cresce

Tivemos tabelas de log na tabela do SQL Server com dezenas de milhões de linhas.

Shiraz Bhaiji
fonte
1

O número 2 parece bom.

Para uma tabela com apenas 4 colunas, não deve ser um problema, mesmo com alguns milhões de linhas. Claro que isso pode depender de qual banco de dados você está usando. Se é algo como o SQL Server, então não haveria problema.

Você provavelmente desejaria criar um índice no campo QuestionID, na tabela tblAnswer.

Obviamente, você precisa especificar qual banco de dados está usando, bem como os volumes estimados.

kevchadders
fonte
0

Parece bastante completo para uma pesquisa simples. Não se esqueça de adicionar uma tabela para 'valores abertos', onde um cliente pode dar sua opinião através de uma caixa de texto. Vincule essa tabela com uma chave estrangeira à sua resposta e coloque índices em todas as suas colunas relacionais para obter desempenho.

Ben Fransen
fonte
1
Existe uma razão pela qual também não pude colocar os comentários na tabela de respostas?
Michael
0

O número 2 está correto. Use o design correto até e a menos que você detecte um problema de desempenho. A maioria dos RDBMS não terá problemas com uma tabela estreita, mas muito longa.

Larry Lustig
fonte
0

Ter uma tabela de respostas grande, por si só, não é um problema. Desde que os índices e restrições estejam bem definidos, você deve estar bem. Seu segundo esquema parece bom para mim.

Dave Swersky
fonte
0

Dado o índice adequado, sua segunda solução é normalizada e boa para um sistema tradicional de banco de dados relacional.

Eu não sei o quão grande é enorme, mas deve conter, sem problemas, alguns milhões de respostas.

Jorge Córdoba
fonte
0

Você pode optar por armazenar o formulário inteiro como uma string JSON.

Não tenho certeza sobre sua exigência, mas essa abordagem funcionaria em algumas circunstâncias.

mriiiron
fonte