sql - sistema - Diseño de la base de datos para una encuesta
sistema de encuestas base de datos (11)
Necesito crear una encuesta donde las respuestas se almacenan en una base de datos. Me pregunto cuál sería la mejor manera de implementar esto en la base de datos, específicamente las tablas requeridas. La encuesta contiene diferentes tipos de preguntas. Por ejemplo: campos de texto para comentarios, preguntas de opción múltiple y, posiblemente, preguntas que podrían contener más de una respuesta (es decir, marque todas las que correspondan).
He encontrado dos posibles soluciones:
Cree una tabla gigante que contenga las respuestas para cada envío de encuesta. Cada columna correspondería a una respuesta de la encuesta. es decir, ID de encuesta, Respuesta1, Respuesta2, Respuesta3
No creo que esta sea la mejor manera ya que hay muchas preguntas en esta encuesta y no parece ser muy flexible si la encuesta va a cambiar.
La otra cosa que pensé fue crear una mesa de preguntas y una tabla de respuestas. La tabla de preguntas contendría todas las preguntas para la encuesta. La tabla de respuestas contendría respuestas individuales de la encuesta, cada fila vinculada a una pregunta.
Un simple ejemplo:
tblSurvey : SurveyID
tblQuestion : QuestionID, SurveyID , QuestionType, Question
tblRespuesta : AnswerID, UserID, QuestionID , Answer
tblUser : UserID , UserName
Mi problema con esto es que podría haber toneladas de respuestas que harían que la tabla de respuestas fuera bastante grande. No estoy seguro de que sea tan bueno cuando se trata de rendimiento.
Agradecería cualquier idea y sugerencia.
Como regla general, modificar un esquema basado en algo que un usuario podría cambiar (como agregar una pregunta a una encuesta) debe considerarse bastante mal. Hay casos en los que puede ser apropiado, especialmente cuando se trata de grandes cantidades de datos, pero se sabe en qué se está metiendo antes de sumergirse. Tener solo una tabla de "respuestas" para cada encuesta significa que agregar o eliminar preguntas es potencialmente muy costoso. , y es muy difícil hacer análisis de una manera agnóstica.
Creo que tu segundo enfoque es el mejor, pero si estás seguro de que vas a tener muchas preocupaciones sobre la escala, una cosa que me ha funcionado en el pasado es un enfoque híbrido:
- Cree tablas de respuestas detalladas para almacenar las respuestas por pregunta tal como ha descrito en 2. En general, esta información no se consultaría directamente desde su aplicación, sino que se usaría para generar datos de resumen para las tablas de informes. Probablemente también desees implementar algún tipo de archivo o eliminación para estos datos.
- Cree también la tabla de respuestas de 1 si es necesario. Esto se puede usar siempre que los usuarios quieran ver una tabla simple para obtener resultados.
- Para cualquier análisis que deba realizarse con fines informativos, programe trabajos para crear datos de resumen adicionales en función de los datos de 1.
Esto es mucho más trabajo para implementar, por lo que realmente no aconsejaría esto a menos que sepa con certeza que esta tabla se encontrará con problemas de escala masiva.
Creo que su modelo n. ° 2 está bien, sin embargo, puede echar un vistazo al modelo más complejo que almacena preguntas y respuestas prefabricadas (respuestas ofrecidas) y les permite ser reutilizados en diferentes encuestas.
- Una encuesta puede tener muchas preguntas; una pregunta puede ser (re) utilizada en muchas encuestas.
- Se puede ofrecer una respuesta (prefabricada) para muchas preguntas. Una pregunta puede tener muchas respuestas ofrecidas. Una pregunta puede tener diferentes respuestas ofrecidas en diferentes encuestas. Se puede ofrecer una respuesta a diferentes preguntas en diferentes encuestas. Hay una respuesta "Otro" predeterminada, si una persona elige otra, su respuesta se registra en Answer.OtherText.
- Una persona puede participar en muchas encuestas, una persona puede responder preguntas específicas en una encuesta solo una vez.
Dado el índice adecuado, su segunda solución se normaliza y es buena para un sistema de base de datos relacional tradicional.
No sé lo grande que es enorme, pero debería contener sin problemas un par de millones de respuestas.
Definitivamente la opción n. ° 2, también creo que podría tener un descuido en el esquema actual, es posible que desee otra tabla:
+-----------+
| tblSurvey |
|-----------|
| SurveyId |
+-----------+
+--------------+
| tblQuestion |
|--------------|
| QuestionID |
| SurveyID |
| QuestionType |
| Question |
+--------------+
+--------------+
| tblAnswer |
|--------------|
| AnswerID |
| QuestionID |
| Answer |
+--------------+
+------------------+
| tblUsersAnswer |
|------------------|
| UserAnswerID |
| AnswerID |
| UserID |
| Response |
+------------------+
+-----------+
| tblUser |
|-----------|
| UserID |
| UserName |
+-----------+
Probablemente, cada pregunta tendrá un número determinado de respuestas de las que el usuario puede seleccionar, luego las respuestas reales se rastrearán en otra tabla.
Las bases de datos están diseñadas para almacenar una gran cantidad de datos, y la mayoría se escala muy bien. No hay una necesidad real de usar una forma normal menor simplemente para ahorrar espacio.
El número 2 es correcto. Use el diseño correcto hasta y a menos que detecte un problema de rendimiento. La mayoría de RDBMS no tendrá un problema con una tabla estrecha pero muy larga.
El segundo enfoque es el mejor.
Si quiere normalizarlo aún más, podría crear una tabla para tipos de preguntas
Las cosas simples para hacer son:
- Coloque la base de datos e inicie sesión en su propio disco, no todo en C como predeterminado
- Cree la base de datos tan grande como sea necesario para que no tenga pausas mientras la base de datos crece
Hemos tenido tablas de registro en SQL Server Table con 10 de millones de filas.
Mi diseño se muestra a continuación.
El último script de creación está en https://gist.github.com/durrantm/1e618164fd4acf91e372
El script y el archivo mysql workbench.mwb también están disponibles en
https://github.com/durrantm/survey
No 2 se ve bien.
Para una tabla con solo 4 columnas, no debería ser un problema, incluso con unos pocos millones de filas. Por supuesto, esto puede depender de la base de datos que esté utilizando. Si es algo así como SQL Server, entonces no sería un problema.
Probablemente desee crear un índice en el campo QuestionID, en la tabla tblAnswer.
Por supuesto, debe especificar qué Base de datos está utilizando, así como los volúmenes estimados.
Parece bastante completo para una encuesta de smiple. No olvide agregar una tabla para ''valores abiertos'', donde un cliente puede brindar su opinión a través de un cuadro de texto. Vincule esa tabla con una clave externa a su respuesta y coloque índices en todas sus columnas relacionales para el rendimiento.
Puede elegir almacenar el formulario completo como una cadena JSON.
No estoy seguro acerca de su requerimiento, pero este enfoque funcionaría en algunas circunstancias.
Tener una gran tabla de respuestas, en sí misma, no es un problema. Siempre que los índices y las restricciones estén bien definidos, debería estar bien. Tu segundo esquema me parece bien.