Donc, j'essaie d'apprendre PHP et MySQL (j'ai une compréhension de base des deux; j'ai lu la première moitié de Head First SQL et Head First PHP & MySQL) et je pense que la meilleure façon de consolider mes connaissances est de construire quelque chose plutôt que de lire.
Dans cet esprit, je voudrais créer une page Web de base qui se connecte à une base de données MySQL sur un serveur. Je vais créer un formulaire HTML de base et permettre aux utilisateurs d'entrer des informations de base, telles que: nom, prénom, email, anniversaire, sexe.
Mon problème est Je ne sais pas comment concevoir une base de données qui enregistrera les résultats d'un quiz de base - je veux seulement 5 problèmes à choix multiples. Finalement, je voudrais afficher les résultats de l'utilisateur par rapport aux résultats des utilisateurs précédents.
Si vous pouviez m'aider à comprendre comment concevoir des tables pour un questionnaire de 5 questions, je vous en serais reconnaissant. Merci!
Je commencerais par 4 tableaux simples:
* User
- user_id auto integer
- regtime datetime
- username varchar
- useremail varchar
- userpass varchar
* Question
- question_id auto integer
- question varchar
- is_active enum(0,1)
* Question_choices
- choice_id auto integer
- question_id integer
- is_right_choice enum(0,1)
- choice varchar
* User_question_answer
- user_id integer
- question_id integer
- choice_id integer
- is_right enum(0,1)
- answer_time datetime
Ma pensée sur cette conception de table est:
User
sert à stocker l'utilisateur enregistré.Question
sert à stocker toutes vos questions. Il a is_active pour que vous puissiez afficher de manière sélective uniquement les questions actives (en utilisant WHERE is_active
= '1')question_choices
sert à stocker toutes les options disponibles. Il a is_right_choice
qui définit quel choix est la bonne réponse à une question particulière.User_question_answer
sert à stocker les réponses de votre utilisateur. Il a is_right
pour une recherche plus rapide, pour voir si ce choix de questions et réponses est correct (basé sur is_right_choice
précédemment défini). Cela a aussi answer_time
juste pour noter quand cet utilisateur particulier répond à la question.Je ne sais pas à quel point vous êtes nouveau dans la programmation en général, mais même si vous débutez, je vous recommanderais d'utiliser un framework.
L'utilisation d'un cadre vous guidera en fournissant des implémentations des meilleures pratiques des outils dont vous aurez besoin dans votre projet.
J'utilise personnellement Symfony pour les projets php, et je vous suggère de consulter leurs guides et tutoriels . Symfony est un cadre bien établi et il est basé sur des conceptions largement acceptées.
Pour répondre à votre question plus directement, je suggérerais quelque chose comme ceci pour votre application:
- user
- id (PK)
- last_name
- first_name
- email
- gender
- quiz
- id (PK)
- title
- quiz_question
- id (PK)
- quiz_id (FK)
- text
- quiz_question_option
- id (PK)
- quiz_question_id (FK)
- text
- is_correct
- quiz_user_answer
- id (PK)
- quiz_question_id (FK)
- quiz_question_option_id // this is the answer.
Ce qui précède vous permettrait de définir plusieurs questionnaires ayant chacun plusieurs questions et de créer des ensembles de réponses (un ensemble de réponses d'un utilisateur à un quiz) et d'enregistrer chaque réponse.
J'espère que cela pourra aider :)
C'était aussi le premier projet que j'ai fait en PHP/MySQL il y a environ 8 ans.
Votre première solution consiste à coder la base de données pour qu'elle corresponde exactement à votre formulaire. Donc, vous voulez enregistrer les utilisateurs et les soumissions de quiz, donc ça va ressembler à ceci:
CREATE TABLE users (
username VARCHAR(16) PRIMARY KEY,
password VARCHAR(8),
email VARCHAR(255),
birthday DATE,
gender ENUM('M', 'F')
);
CREATE TABLE quiz_answers (
username VARCHAR(16) REFERENCES users,
question1 VARCHAR(10),
question2 INT,
question3 ENUM('YES', 'NO', 'MAYBE'),
question4 BOOLEAN,
question5 VARCHAR(25),
submitted_at DATETIME,
PRIMARY KEY (username, submitted_at)
);
Il ne s'agit donc que d'enregistrer le strict minimum: l'utilisateur et les soumissions de quiz. J'ai donné des types de réponses que vous auriez à rendre spécifiques à votre quiz réel. J'ai également fait une réponse désactivée l'utilisateur et le moment où ils l'ont soumis; vous êtes plus susceptible d'utiliser une clé de substitution (AUTO_INCREMENT
), mais j'aime autant que possible résister aux substituts.
Dès le départ, il y a une violation de 1NF: questionN
. Si vous faisiez cela correctement, vous nommeriez ces colonnes d'après ce qu'elles signifient, et pas seulement de quelle question elles sont. Mais normaliser cela est vraiment la prochaine étape vers des formulaires extensibles, mais qui suivent l'historique.
Donc, la prochaine chose que vous remarquerez est que vraiment un quiz est une collection de questions, chacune ayant une collection de réponses possibles. Et puis une soumission de formulaire relie vraiment un ensemble de réponses sélectionnées à leurs questions, sur un formulaire de quiz particulier, par un utilisateur de quiz particulier. Cela ressemble à une relation à quatre: utilisateur, quiz, question, réponse. Vous pouvez en rogner un si cela ne vous dérange pas de répéter des questions sur différents questionnaires, mais pour être complet, allons dans cette direction. Remplacer quiz_answers
ci-dessus avec ceci:
CREATE TABLE questions (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
question TEXT
);
CREATE TABLE answers (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
question_id INTEGER REFERENCES questions,
answer VARCHAR(255)
);
CREATE TABLE quizzes (
name VARCHAR(255) PRIMARY KEY,
);
Nous n'avons pas vraiment de métadonnées spéciales pour un quiz, donc c'est juste un nom pour l'instant.
Alors maintenant, vous avez besoin d'une relation un-à-plusieurs des questions aux réponses et des questionnaires aux questions.
CREATE TABLE question_answers (
question_id INTEGER REFERENCES questions,
answer_id INTEGER REFERENCES answers,
idx INTEGER,
PRIMARY KEY (question_id, answer_id)
);
CREATE TABLE quiz_questions (
quiz_name VARCHAR(255) REFERENCES quizzes,
question_id INTEGER REFERENCES questions,
idx INTEGER,
PRIMARY KEY (quiz_name, question_id)
);
La partie délicate, comme mentionné ci-dessus, est la relation d'ordre supérieur entre l'utilisateur et la soumission du formulaire, et le lien entre les questions du formulaire et les réponses de l'utilisateur. J'ai décidé de séparer cela en deux tableaux pour éviter une répétition.
CREATE TABLE quiz_submissions (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(16) REFERENCES users,
quiz_name VARCHAR(255) REFERENCES quizzes,
submitted_at DATETIME
);
CREATE TABLE submission_answer (
submission_id INTEGER REFERENCES quiz_submissions,
question_id INTEGER REFERENCES questions,
answer_id INTEGER REFERENCES answers,
PRIMARY KEY (submission_id, question_id)
);
C'est assez bien normalisé à ce stade. Vous pouvez voir que cela sera également un peu plus difficile à interroger. Pour obtenir toutes les questions d'un quiz, vous devrez vous connecter du quiz aux questions. Vous pouvez soit joindre à partir de là sur les réponses pour faire une grande requête pour obtenir toutes les données dont vous avez besoin pour créer le formulaire (en plus d'avoir à faire plus de post-traitement) ou vous pouvez frapper la base de données une fois de plus pour chaque question et faire moins de post-traitement. Je peux argumenter de toute façon. Pour obtenir toutes les réponses d'un utilisateur en particulier, vous devrez sélectionner parmi user_submissions avec l'ID de quiz et le nom d'utilisateur dans la table de soumission_ réponse à la question et la réponse choisie par l'utilisateur. L'interrogation va donc devenir rapidement intéressante. Vous perdrez votre peur des jointures, si vous en avez une.
J'espère que cela ne vous éloignera pas trop des bases de données relationnelles; en faisant cela, vous faites, en fait, un modèle relationnel à l'intérieur du modèle relationnel, bien qu'une forme restreinte.
Je me rends compte que l'utilisation de nombreuses clés naturelles comme je l'ai fait ci-dessus est un peu peu orthodoxe de nos jours. Cependant, je vous recommande de l'essayer, au moins pendant que vous commencez, car il sera beaucoup plus facile de voir comment les jointures doivent fonctionner si elles ne sont pas toutes des entiers compris entre 1 et 10.
Eh bien, en ce moment, je suis dans une phase de développement et je rencontre toujours des problèmes (c'est-à-dire la synchronisation des états ronds entre le serveur et le client), mais cela peut vous aider
P.S .: ne stockez pas les mots de passe dans la base de données, comme dans l'image ci-dessus - stockez les mots de passe hachés à la place