Melhor estrutura de tabelas para o problema

3 respostas
Y

Boa noite Pessoal, estou com uma dúvida gigante sobre como estruturar o banco de dados da aplicação que estou desenvolvendo para um trabalho da faculdade.

Imaginem um sistema em que o usuário vai responder diversas perguntas com opções de respostas parametrizadas, como se fosse uma entrevista. Por exemplo:

Sexo : ()Masculino ()Feminino
Se acorda durante a noite para ir ao banheiro, qual é a frequência? ( ) 1 a 2 vezes ( ) 3 a 4 vezes ( ) 5 a 6 vezes ( ) mais de 6 vezes por noite

A estrutura que pensei foi uma tabela para Perguntas, uma tabela para Alternativas de respostas, pois não sei quantas respostas pode ter uma pergunta e nem quantas perguntas podem existir na pesquisa, uma tabela Questionário para saber quem respondeu as perguntas e vincular o ID do questionário a uma outra tabela de Respostas, para saber quais foram as respostas selecionadas.

Poderiam me dar alguma ideia melhor ou me dizer se o que pensei está bom?
Obrigado.

3 Respostas

wldomiciano

Também gostaria de saber a opinião de outras pessoas. Tive uma ideia assim:

CREATE TABLE `questao` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `conteudo` VARCHAR(255) NOT NULL
);

CREATE TABLE `alternativa` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `conteudo` VARCHAR(255) NOT NULL,
  `questao_id` INT UNSIGNED,
  FOREIGN KEY (`questao_id`) REFERENCES `questao`(`id`) ON DELETE CASCADE
);

CREATE TABLE `usuario` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `nome` VARCHAR(255) NOT NULL
);

CREATE TABLE `resposta` (
  `usuario_id` INT UNSIGNED,
  `alternativa_id` INT UNSIGNED,
  `extra` VARCHAR(255) DEFAULT NULL,
  FOREIGN KEY (`usuario_id`) REFERENCES `usuario`(`id`) ON DELETE CASCADE,
  FOREIGN KEY (`alternativa_id`) REFERENCES `alternativa`(`id`) ON DELETE CASCADE
);

No caso, a tabela resposta tem o campo extra pro caso de exigir que o usuário escreva a resposta, sabe?

Aí vc faria um SELECT assim:

SELECT
  usuario.nome,
  questao.conteudo AS questao,
  reposta.conteudo AS reposta,
  reposta.extra AS extra
FROM usuario
JOIN resposta ON resposta.usuario_id = usuario.id
JOIN alternativa ON alternativa.id = reposta.alternativa_id
JOIN questao ON questao.id = alternativa.questao_id;

Eu não pude testar muito e também não pensei em muitos possíveis cenários então realmente espero que outros respondam também.

Enquanto isso, o que vc acha?

Y

Nossa foi quase o que pensei, mas tenho dúvida quanto a performance.
Vamos supor que eu tenha em torno de 80 questões, isso iria gerar 80 linhas de resposta para cada usuário.

Mas não consigo imaginar outra estrutura a não ser assim, o que tu acha da performance?
Sei que não preciso me preocupar com isso, por se tratar de um trabalho de faculdade, mas fiquei pensando kkkk

wldomiciano

Que bom que está considerando performance desde já.

Se vc tem 80 questões, faz sentido retornar, pelo menos, 80 linhas.

Acho que o problema fica por conta de quando uma mesma questão pode ter mais de uma resposta. Imagina 80 questões de multipla escolha e em cada uma delas o usuario seleciona 2 alternativas, com o select que mostrei vc teria 160 linhas!

Dependendo da situação vc não vai conseguir fugir disso. Em outras, vc poderia remover algumas colunas do select e pedir pra trazer apenas as alternativas. E vc também poderia trazer tudo do banco e processar com sua linguagem de programação escolhida e retornar um JSON tipo assim:

[
  {
    "nome": "Fulano",
    "questoes": [
      {
        "conteudo": "Sexo",
        "respostas": [
          {
            "conteudo": "Masculino",
            "extra": null
          }
        ]
      }
    ]
  }
]

Ia ser legal ver o que os outros respondem. Quando ouço falar de performance em banco de dados, o assunto quase sempre está relacionado com a quantidade de selects que vc precisa fazer, eu ainda não ouvi falar se a quantidade de linhas é um problema. Mas eu também estou aprendendo.

Criado 29 de setembro de 2020
Ultima resposta 30 de set. de 2020
Respostas 3
Participantes 2