MaxQ
MaxQ

Reputation: 605

Best method for storing quiz results in MySQL

I'm trying to record test/quiz scores in a database. What's the best method to do this when there might be a lot of tests and users?

These are some options I considered: should I create a new column for each quiz and row for users, or does this have its limitations? Might this be slow? Should i create a new row for each user & quiz? Should I stick to my original 'user' database and encode it in text?

Elaborating a little on the plan: JavaScript Quiz, submits score with AJAX, and a script sends it to the database. I'm new with php so i'm not sure about a good approach.

Any help would be greatly appreciated :) this is for a school science fair

Upvotes: 1

Views: 3288

Answers (3)

jave.web
jave.web

Reputation: 15032

Definitely do not create dynamic columns! (no column for each quiz). Also adding columns to user table (or generally any table) when they are not identifying the user(or generally any table item) is bad aproach...

This is pretty example of normalization, you should avoid storing any redundant rows. To do that you would create 3 tables and foreign keys to ensure scores are always referencing an existing user and quiz. E.g.:

  1. users - id, nickname, name
  2. quizzes - id, quizName, quizOtherData
  3. scores - id, user_id (references users.id) , quiz_id , (ref. quizzes.id), score

And then add rows to scores table per user per quiz. Additionaly you could create UNIQUE key for columns user_id and quiz_id to disallow users to complete one quiz more times than one.

This will be fast and will not store redundant (unneeded extra) data.

To get results of quiz with id e.g. 4 and user info of people who's submitted this quiz, ordered from highest to lowest score, you would do query like:

SELECT users.*, scores.score
FROM scores RIGHT JOIN users ON(users.id=scores.user_id)
WHERE scores.quiz_id = 4
ORDER BY score DESC

Reason why I used RIGHT join here is because there might be users that didn't do this quiz, however every score always have an existing user&quiz (due to foreign keys

To get overall info of all users, quizes and scores you would do something like:

SELECT * 
FROM quizzes 
LEFT JOIN scores ON(quizzes.id=scores.quiz_id)
LEFT JOIN users ON(users.id=scores.user_id)
ORDER BY quizzes.id DESC, scores.score DESC, users.name ASC

BTW: If you are new to PHP (or anybody reading this), use PHP's PDO interface to communicate with your database :) AVOID functions like mysql_query, at least use mysqli_query, but for portability I would recommend stay with PDO.

Upvotes: 0

Surreal Dreams
Surreal Dreams

Reputation: 26380

I'd suggest 3 data tables in your database: students, tests, and scores.

Each student needs to have fields for an ID and whatever else (name, dob, etc) you want to record about them. Tests should have fields for an ID and whatever else (name, date, weight, etc). Scores should have the student ID, a test ID, and the score (any anything else).

This means you can query a student and join with the scores table to get all the student's scores. You can also join the test table these results to get labels put onto each score and calculate a grade based on scores and weight.

Alternately you can query for a test and join with the scores to get all the scores on a given test to get the class stats.

Upvotes: 1

franka
franka

Reputation: 1917

I would say create a database table, maybe one that lists all students(name, dob, student id), and then one for all tests(score, date, written by). Will only you access the db, or can your students access it too? If the latter is the case, you need to make sure the create accurate security or "views" to ensure the student can only see their own grades at a time (not everyone's).

Upvotes: 0

Related Questions