Bonjour à tous,
je me pose certaines questions sur ma manière de procéder sur une problématique de classement à un QCM, voilà mon cas:
Je propose des QCM de 10 questions max avec entre 2 à 4 choix possibles, 1 seul des choix étant correct.
Les réponses des utilisateurs sont enregistrés sous la forme d'une chaine de caractères numériques où le numéro inscrit correspond à la radiobox coché (ex s'il coche que les 1ères radiobox de chaque question du QCM => 0000000....)
J'enregistre le tout sous la table suivante => membre_id mediumint(8), qcm_id smallint(4), reponse int(10)
où les champs membre_id, qcm_id sont des index et le couple membre_id,qcm_id est un index unique
(Noter que cette table peut devenir très volumineuse le nb d'utilisateur et de QCM augmentant)
Pour calculer le score des utilisateurs et leur classement, je compare leur réponse au résultat officiel (ex: $bonne_reponse='1234512345'
Ma problématique est dans ma manière de faire, si celle ci me semble correcte quand il y a peu d'utilisateurs,
je me demande si ce serait toujours le cas, s'il devait y en avoir beaucoup plus (potentiellement des centaine de milliers) (soyons optimistes)
Je procède ainsi, ce sera plus facile à comprendre:
1) je sélectionne les réponses de tous les membres ayant répondu au questionnaire en une seule requête:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $a=strlen($bonne_reponse); // le nb de caractères de la bonne réponse correspondant au nombre de questions du QCM $quoi=array(); // ici sera inséré le score des utilisateurs $zql=array();
la table ma_table est là où sont enregistrées toutes les réponses des membres aux différents qcm
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $sql='SELECT membre_id,reponse FROM ma_table WHERE qcm_id='.$value; $result=mysql_query($sql) or die('Echec 1'); $num=mysql_num_rows($result);
2) je calcule pour chaque ligne retourné, donc chaque membre, son score en comparant sa réponse à la bonne réponse (je schématise):
Notez que l'array quoi (ainsi que ci après l'array zql) pourrait avoir des centaines de millers d'entrée, y aura -t-il une problématique à cela ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 while ($Res = mysql_fetch_row($result) ){ $k=0; for($i=0;$i<$a;$i++)if($bonne_reponse[$i]==$Res[1][$i])$k++; $quoi[$Res[0]]=$k; // le score de l'utilisateur membre_id=$Res[0] vaut $k }
3) pour faire le classement je trie par ordre décroissant le tableau des scores en conservant les clés = id des membres
4) Après avoir préalablement créé une table spécifique à ce questionnaire-là (donc vide), j'y insère dans l'ordre voulu les membres_id et leur score
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 arsort($quoi); foreach ($quoi as $key => $val) { $zql[]='('.$key.','.($val*10).')'; // $key représente membre_id et $val son score (ici dans l'ordre décroissant) }
Question => la requête INSERT multiple est-elle efficace pour des centaines de miliers de lignes à insérer ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 $sql2='INSERT INTO qcm_'.$value.' (membre_id,score) VALUES '.implode(',',$zql); $result2=mysql_query($sql2) or die('Echec 2');
La table specifique serait ainsi faite => id (auto_increment), membre_id (index unique), score // ainsi en lisant l'id du membre, on a son classement
5) Enfin, je dois incrémenter le score total de chaque utilisateur sur une table_score existante, malheureusement je crois être obligé de passé par une boucle:
Bref, voilà donc comment je compte procéder, je n'ai finalement que 2 requêtes toutes simples mais pouvant porter sur un très grand nombre de lignes,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 for($j=0;$j<$num;$j++){ $sql3="UPDATE table_score SET score=score+".$zql[$j][1]." WHERE membre_id='".$zql[$j][0]."'"; $result3=mysql_query($sql3) or die('Echec 3'); }
ainsi qu'une 3ème requête Update toute aussi simple mais répétée potentiellement un très grand nombre de fois
Voyez-vous des moyens d'améliorer tout cela, voyez-vous des erreurs ou des améliorations que je pourrais porter à ce script ?
Pour faire court, vos avis, critiques et conseils seront la bienvenue
PS: ce script sera executé en tâche cron pendant la nuit vers les 3h du mat', l'idéal est biensur qu'il dure le moins longtemps possible,
mais si vous pensez qu'il durerea un temps raisonnable sur le serveur dédié suivant http://www.soyoustart.com/fr/offres/sys-e32-1.xml , cela me conviendra
D'ailleurs si vous pourriez me conseillé des modif à effectuer du côté de mysql je suis preneur aussi
Merci d'avance
A bientôt
Partager