¿Qué tablas y relaciones de database de MySQL soportarían una encuesta de preguntas y respuestas con preguntas condicionales?

Estoy trabajando en un sistema de encuestas bastante simple en este momento. El esquema de la database va a ser simple: una tabla de Survey , en una relación de uno a muchos con la tabla de Question , que está en una relación de uno a muchos con la tabla de Answer y con la tabla de Answer PossibleAnswers .

Recientemente, el cliente se dio count de que desea poder mostrar ciertas preguntas solo a las personas que dieron una respuesta concreta a alguna pregunta anterior (por ejemplo, ¿compra cigarrillos ? , ¿ iría seguido de cuál es su marca de cigarrillos favorita?, No tiene sentido preguntar a los segundos; pregunta a un no fumador).

Ahora comencé a preguntarme cuál sería la mejor manera de implementar estas preguntas condicionales en términos de mi esquema de database. Si la question A tiene 2 respuestas posibles: A y B, y la question B solo debería aparecerle a un usuario si la respuesta fue A ?

Editar: Lo que estoy buscando es una forma de almacenar esa información sobre los requisitos en una database. El event handling los datos se realizará probablemente en el lado de la aplicación, ya que mis habilidades SQL son malas;)

Diseño de la database

Última actualización: 5/3/2015
Diagtwig y files SQL ahora disponibles en https://github.com/durrantm/survey

enter image description here

Si usa esta respuesta (superior) o cualquier elemento, ¡agregue comentarios sobre las mejoras!

Este es un clásico real, hecho por miles. Siempre parecen 'bastante simples' para empezar, pero para ser bueno, en realidad es bastante complejo. Para hacer esto en Rails, usaría el model que se muestra en el diagtwig adjunto. Estoy seguro de que parece algo demasiado complicado para algunos, pero una vez que haya construido algunos de estos, a lo largo de los años, se dará count de que la mayoría de las decisiones de layout son patrones muy clásicos, mejor abordados por una estructura de datos flexible y dinámica en el comienzo.
Más detalles a continuación:

Detalles de la tabla para tablas key

respuestas

La tabla de respuestas es crítica ya que captura las respuestas reales de los usuarios. Notarás que las respuestas enlazan con question_options , no con preguntas . Esto es intencional.

input_types

input_types son los types de preguntas. Cada pregunta solo puede ser de 1 tipo, por ejemplo, todos los diales de radio, todos los campos de text, etc. Utilice preguntas adicionales para cuando haya (digamos) 5 diales de radio y 1 checkbox para "include". opción o alguna combinación de este tipo. Etiquete las dos preguntas en la vista de usuarios como una pero internamente tiene dos preguntas, una para los diales de radio, una para la checkbox. La checkbox tendrá un grupo de 1 en este caso.

option_groups

option_groups y option_choices le permiten build grupos 'comunes'. Un ejemplo, en una aplicación de bienes raíces podría ser la pregunta '¿Qué edad tiene la propiedad?'. Las respuestas pueden ser deseables en los ranges: 1-5 6-10 10-25 25-100 100+

Luego, por ejemplo, si hay una pregunta sobre la antigüedad de la propiedad contigua, la encuesta querrá 'reutilizar' los ranges anteriores, de modo que se use el mismo grupo de opciones y opciones.

unidades de medida

units_of_measure es como suena. Ya sean pulgadas, tazas, píxeles, ladrillos o lo que sea, puede definirlo una vez aquí.

FYI: aunque es de naturaleza genérica, se puede crear una aplicación además de este, y este esquema es muy adecuado para el marco Ruby On Rails con convenciones como "id" para la key principal de cada tabla. Además, las relaciones son todas simples one_to_many's sin muchos_a_manios o has_many throughs necesarios. Probablemente agregaría has_many: throughs y / o delegates para get cosas como survey_name de una respuesta individual fácilmente sin.multiple.caining.

También podría pensar en reglas complejas y tener un campo de condición basado en cadenas en su tabla de Preguntas, aceptando / parsing cualquiera de estas:

  • A (1) = 3
  • ((A (1) = 3) y (A (2) = 4))
  • A (3)> 2
  • (A (3) = 1) y (A (17)! = 2) y C (1)

Donde A (x) = y significa "Respuesta de la pregunta x es y" y C (x) significa la condición de la pregunta x (el valor pnetworkingeterminado es verdadero) …

Las preguntas tienen un campo de order y las examinará una a una, salteando preguntas donde la condición es FALSA.

Esto debería permitir encuestas de cualquier complejidad que desee, su GUI podría crearlas automáticamente en "Modo simple" y permitir y "Modo avanzado" donde un usuario puede ingresar las ecuaciones directamente.

una forma es agregar una tabla 'requisitos de pregunta' con campos:

  • question_id (enlace a la pregunta "¿qué marca?")
  • requinetworking_question_id (enlace a la pregunta "¿fuma?")
  • requinetworking_answer_id (enlace a la respuesta "sí")

En la aplicación, consulte esta tabla antes de plantear una determinada pregunta. Con una tabla separada, es fácil agregar las respuestas requeridas (agregar otra fila para la respuesta "a veces", etc.)

Personalmente, en este caso, usaría la estructura que describió y usaría la database como un mecanismo de almacenamiento tonto. Soy partidario de poner estas restricciones complejas y dependientes en la capa de aplicación.

Creo que la única forma de hacer cumplir estas restricciones sin crear nuevas tablas para cada pregunta con keys externas para otros, es usar el material de T-SQL u otros mecanismos específicos del vendedor para generar activadores de database para hacer cumplir estas restricciones.

A nivel de aplicación, tienes muchas más posibilidades y es más fácil de portar, por lo que preferiría esa opción.

Espero que esto te ayude a encontrar una estrategia para tu aplicación.