web-dev-qa-db-fra.com

Quelles tables et relations de base de données mysql prendraient en charge une enquête Q&R avec des questions conditionnelles?

Je travaille actuellement sur un système d'enquête assez simple. Le schéma de la base de données va être simple: une table Survey, dans une relation un-à-plusieurs avec la table Question, qui est dans une relation un-à-plusieurs avec la Answer table et avec la table PossibleAnswers.

Récemment, la cliente a réalisé qu'elle souhaitait pouvoir montrer certaines questions uniquement aux personnes ayant donné une réponse particulière à une question précédente (par exemple. Achetez-vous des cigarettes? serait suivi de Quelle est votre marque de cigarette préférée? , inutile de poser la deuxième question à un non-fumeur).

Maintenant, j'ai commencé à me demander quelle serait la meilleure façon de mettre en œuvre ces questions conditionnelles en termes de schéma de base de données? Si question A a 2 réponses possibles: A et B, et question B ne devrait apparaître qu'à un utilisateur si la réponse était A?

Edit: Ce que je recherche, c'est un moyen de stocker ces informations sur les exigences dans une base de données. Le traitement des données se fera probablement côté application, car mes compétences SQL sont nulles;)

43
kender

Conception de la base de données d'enquête

Dernière mise à jour: 5/3/2015
Diagramme et fichiers SQL désormais disponibles sur https://github.com/durrantm/survey

enter image description here

Si vous utilisez cette réponse (en haut) ou tout autre élément, veuillez ajouter des commentaires sur les améliorations !!!

C'est un vrai classique, fait par des milliers. Ils semblent toujours "assez simples" au départ, mais pour être bon, c'est en fait assez complexe. Pour ce faire en Rails j'utiliserais le modèle montré dans le diagramme ci-joint. Je suis sûr que cela semble bien trop compliqué pour certains, mais une fois que vous en avez construit quelques-uns, sur le années, vous vous rendez compte que la plupart des décisions de conception sont des schémas très classiques, mieux traités au départ par une structure de données flexible et dynamique.
Plus de détails ci-dessous:

Détails du tableau pour les tableaux clés

réponses

Le tableau des réponses est essentiel car il capture les réponses réelles des utilisateurs. Vous remarquerez que les réponses aux liens vers question_options , pas les questions . C'est intentionnel.

types_entrée

types_entrée sont les types de questions. Chaque question ne peut être que de 1 type, par ex. tous les numéros de radio, tous les champs de texte, etc. Utilisez des questions supplémentaires pour savoir quand il y a (disons) 5 numéros de radio et 1 case à cocher pour "inclure?" option ou une telle combinaison. Étiquetez les deux questions dans la vue des utilisateurs comme une, mais en interne, vous avez deux questions, une pour les appels radio, une pour la case à cocher. La case à cocher aura un groupe de 1 dans ce cas.

groupes_options

option_groups et option_choices vous permettent de créer des groupes 'communs'. Par exemple, dans une demande immobilière, il pourrait y avoir la question "Quel âge a la propriété?". Les réponses peuvent être souhaitées dans les plages: 1-5 6-10 10-25 25-100 100+

Ensuite, par exemple, s'il y a une question sur l'âge de la propriété adjacente, alors l'enquête voudra "réutiliser" les plages ci-dessus, de sorte que le même groupe d'options et les mêmes options soient utilisés.

unités de mesure

units_of_measure est comme ça sonne. Que ce soit des pouces, des tasses, des pixels, des briques ou autre, vous pouvez le définir une fois ici.

FYI: Bien que de nature générique, on peut créer une application en plus de cela, et ce schéma est bien adapté au cadre Ruby on Rails avec des conventions comme "id" pour la clé primaire de chaque table. De plus, les relations sont toutes simples de one_to_many, sans traversées many_to_many ou has_many nécessaires. J'ajouterais probablement has_many: throughs et/ou: delegates pour obtenir des choses comme survey_name à partir d'une réponse individuelle facilement sans.multiple.chaining.

128
Michael Durrant

Vous pouvez également penser à des règles complexes et avoir un champ de condition basé sur une chaîne dans votre table Questions, acceptant/analysant l'une de ces conditions:

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

Où A (x) = y signifie "La réponse à la question x est y" et C(x) signifie la condition de la question x (la valeur par défaut est vraie) ...

Les questions ont un champ de commande, et vous les parcourriez une par une, en sautant les questions lorsque la condition est FAUX.

Cela devrait permettre des enquêtes de toute complexité que vous souhaitez, votre interface graphique pourrait les créer automatiquement en "mode simple" et autoriser et "mode avancé" où un utilisateur peut entrer directement les équations.

13
Osama Al-Maadeed

une façon consiste à ajouter un tableau "exigences de question" avec des champs:

  • question_id (lien vers la question "quelle marque?")
  • required_question_id (lien vers la question "fumez-vous?")
  • required_answer_id (lien vers la réponse "oui")

Dans l'application, vous vérifiez ce tableau avant de poser une certaine question. Avec un tableau séparé, il est facile d'ajouter les réponses requises (en ajoutant une autre ligne pour la réponse "parfois" etc ...)

9
tehvan

Personnellement, dans ce cas, j'utiliserais la structure que vous avez décrite et utiliserais la base de données comme mécanisme de stockage stupide. Je suis fan de mettre ces contraintes complexes et dépendantes dans la couche application.

Je pense que la seule façon d'appliquer ces contraintes sans créer de nouvelles tables pour chaque question avec des clés étrangères à d'autres, est d'utiliser le truc T-SQL ou d'autres mécanismes spécifiques au fournisseur pour créer des déclencheurs de base de données pour appliquer ces contraintes.

Au niveau de l'application, vous avez tellement plus de possibilités et il est plus facile de porter, donc je préférerais cette option.

J'espère que cela vous aidera à trouver une stratégie pour votre application.

5
TomHastjarjanto