Création d'un QCM - PHP - Programmation
Marsh Posté le 02-12-2020 à 16:13:08
Ton schéma de base n'est pas bon, pour être un peu plus propre et optimisé (pas de donnée redondantes et identiques) tu devrais avoir :
- une table test avec id_test / lib_test.
- une table question avec id_question (id_test clef etrangere), lib_question
- une table réponse avec id_reponse (id_question clef etrangere), lib_reponse
- une table member_reponse avec id (clef unique auto increment), id_question, id_reponse , id_member (les trois en clef etrangere et unique)
De cette façon tu peux trouver a chaque page toutes les réponses de l'utilisateur auquel il a déjà répondu (ou celle auquel il n'a pas répondu avec un LEFT JOIN [...] WHERE id_member = NULL.
Fait quelques tutos sur les bons schémas de base de donnée et les jointures.
Marsh Posté le 02-12-2020 à 16:24:50
Merci pour ta réponse.
Je veux bien te croire que les bases sont loin d'être optimisées, cependant je ne vois pas en quoi le fait de les découper résoudra ma problématique de tirage aléatoire de la question qui n'a pas encore eu de réponse.
Du moins, je ne vois pas comment je pourrais le faire.
Ce que j'ai oublié de préciser, c'est que chaque question à des réponses bien spécifiques qui lui sont rattachées.
Ce ne sont pas des réponses au hasard.
Marsh Posté le 02-12-2020 à 16:42:42
Tu enregistres les réponses dans la base de donnée non ?
Donc avec une jointure tu devrais pouvoir trouver les id_question qui n'ont pas d'id_member et dont la jointure sera impossible (avec un ON ou WHERE id_member != $id_member par exemple).
Mais en vrai ce serait sans doute moins couteux en ressource de garder dans une session un array de questions répondu...
Marsh Posté le 02-12-2020 à 16:55:26
mechkurt a écrit : Tu enregistres les réponses dans la base de donnée non ? |
Oui oui.
Je vais voir la possibilité de split les bases créées comme tu me l'as suggéré.
Ne te méprends pas, je suis content que tu m'aides. Je ne sais pas faire, du coup j'essaie de voir comment je peux mettre en pratique ta solution.
Merci à toi
Marsh Posté le 02-12-2020 à 22:52:18
Dans ta table QCM, c'est normal que on id_test, ça soit un int(1) alors que dans l'autre table, c'est un int(10)
Au passage, tous tes id devraient être des unsigned vu qu'ils vont être > 0
Marsh Posté le 03-12-2020 à 00:16:48
rufo a écrit : Dans ta table QCM, c'est normal que on id_test, ça soit un int(1) alors que dans l'autre table, c'est un int(10) |
Je dirai que oui. Il y a que 75 entrées environs dans la table qcm. Dans l'autre table c'est sensé être à l infini.
Ca change quelque chose ?
Marsh Posté le 03-12-2020 à 08:11:45
T'as conscience que INT(1), ça veut dire un INT affiché sur 1 chiffre ? Donc de 0 à 9 ? Pour aller à 75, ça va être un peu court
Par contre, je comprends pas pourquoi dans QCM, t'as un champ id qui est manifestement la clé primaire du QCM et un champ id_test. Dans la tablet des questions/réponses, je pensais que id_test était une clé étrangère pointant sur la table QCM d'où mon interrogation sur la différence de type.
Marsh Posté le 03-12-2020 à 09:08:08
rufo a écrit : T'as conscience que INT(1), ça veut dire un INT affiché sur 1 chiffre ? Donc de 0 à 9 ? Pour aller à 75, ça va être un peu court |
Oui je suis conscient. id_test sera sur un digit. 1,2,3,4 en l'occurrence.
rufo a écrit :
|
J aurai a terme 4 tests en tout. D ou id_test dans ma base. L id tout court c'est pour les entrées. .
Marsh Posté le 03-12-2020 à 14:00:49
Certes mais pourquoi dans ta table des réponses, tu as mis id_test en int(10) ? C'est pas cohérent.
Marsh Posté le 08-12-2020 à 12:08:46
Salut à tous.
Après une pause, car ma tête allait exploser, j'ai repris le developpement.
J'ai donc recréée 3 tables, comme me l'a suggéré mechkurt :
Table questions :
Table réponses :
Table résultats :
Actuellement :
La table question est remplie avec 14 questions.
La table réponse est remplie avec 75 reponses
La table résultat avec 4 entrées de test.
Je fais cette requête pour aller chercher dans la table "questions" l'id_question qui ne se trouve pas dans la table "resultats". Je me suis inspiré de ce site https://algocool.fr/types-jointures-sql/ pour les jointures.
$question = $mysqli->query("select * from questions LEFT JOIN resultats ON questions.id_question = resultats.id_question WHERE questions.id_question IS NULL"
Pour afficher le résultat :
$j=0;
while ($row2 = $question->fetch_assoc())
{
echo $row2['id_question'];
$j++;
}
Dans ma table resultats j'ai comme id_questions : 1 2 3.
Normalement, avec la requête, je devrais avoir comme valeurs affichés tout sauf 1 2 3, soit : 4 5 6 7 etc jusqu'a 14 (les id_questions de ma table questions).
Or ca m'affiche 0.
Je viens de refaire un test en faisant "WHERE questions.id_question IS NOT NULL"
Ca m'affiche 1 2 3 comme id_question de ma table resultats et non 4 5 6 7 .. de ma table questions
Marsh Posté le 08-12-2020 à 12:42:06
Ca marche PRESQUE
J'ai pris cette requête :
$question = $mysqli->query("SELECT * FROM questions LEFT JOIN resultats ON questions.id_question = resultats.id_question WHERE resultats.id_question IS NULL"
et au lieu de echo $row2['id_question']; j'ai mis echo $row2['question'];
Tous les bons libellés s'affichent !!
Bizarre, quand je mets echo $row2['id_question']; les id ne s'affichent pas par contre
Marsh Posté le 08-12-2020 à 13:08:51
Bon super, ca fonctionne.
Je suis allé récupérer la variable couple_qr qui me permet de faire la correspondance entre la question et les réponses associées.
Donc j'ai bien réussi à récupérer le libellé de la question avec son numéro. Ca me permettra d'aller chercher les réponses.
Merci pour votre aide et merci mechkurt
Marsh Posté le 08-12-2020 à 13:10:34
Encore une fois, pourquoi id_test est dans une table un int(1) et dans les 2 autres tables, un int(10)
Marsh Posté le 08-12-2020 à 14:09:01
Pour tester tes jointure, je te conseille de tester en récupérant toutes les clefs de tes tables (et sur un nombre limité de possibilité sinon tu aura clef x clef ligne) et sans WHERE ni GROUP BY, en voyant tes données dans phpmyadmin je penses que tu comprendras mieux sur quoi il faut filtrer (ON ou WHERE) et sur quoi tu veux agréger (GROUP BY).
Marsh Posté le 08-12-2020 à 15:08:35
rufo a écrit : Encore une fois, pourquoi id_test est dans une table un int(1) et dans les 2 autres tables, un int(10) |
J'ai repris des infos de l ancienne table, sans correction.
Je vais effectivement ajuster
Marsh Posté le 08-12-2020 à 15:09:27
mechkurt a écrit : Pour tester tes jointure, je te conseille de tester en récupérant toutes les clefs de tes tables (et sur un nombre limité de possibilité sinon tu aura clef x clef ligne) et sans WHERE ni GROUP BY, en voyant tes données dans phpmyadmin je penses que tu comprendras mieux sur quoi il faut filtrer (ON ou WHERE) et sur quoi tu veux agréger (GROUP BY). |
Merci pour l'astuce
Marsh Posté le 02-12-2020 à 15:48:38
Salut mes devs szurs.
Toujours dans le cadre de mon projet, je suis en train de me casser la tête pour créer un QCM.
J'ai créé 2 tables.
Dans la 1ere, j'ai injecté les questions avec un id_question propre à chaque question.
J'ai également injecté les réponses (2 mini et 4 maxi) avec un id_reponse.
Dans la 2eme table, je stocke l'id de l'utilisateur qui va passer le test, avec l'enregistrement de l'id_question, id_reponse, a chaque fois que l'utilisateur répondra à la question.
Voici la structure de la table QCM :
Voici la structure de la table qui enregistre les réponses :
Dans l'idée ce que je veux faire :
Lorsque l'utilisateur démarre le test :
Une question est tirée au hasard de la table QCM, avec les réponses associées.
Lorsque l'utilisateur répond à une question : l'id de la question et l'id la réponses, entre autres, sont enregistrées dans la base.
Ca j'arrive à le faire avec l'attribut 'ORDER BY RAND() LIMIT 0,1' dans la requete SQL. Je récupère l'ID de la question qui s'est affichée et je fais chercher les réponses associées à l'ID de la question.
Par contre là où je bloque, c'est que je n'arrive pas à faire en sorte que la question à la quelle l'utilisateur a déjà répondue ne s'affiche pas une deuxième fois.
Une des pistes qui revient souvent sur les internets, c'est la création d'un array qui embarquera tous id_questions et qui, au fur et à mesure des réponses, se réduira jusqu'à épuisement parce que l'utilisateur aura répondu à toutes les questions.
Et une requete SQL qui piochera au hasard dans cet array l'id de la question disponible.
Mes requêtes actuelles :
Pour générer aléatoirement la question :
Merci pour votre aide.
---------------
They see me postin', they hatin', alertin' and tryna catch me trollin' dirty