views:

96

answers:

5

hi! I'm developing a quiz module for a school with php and mysql. The requirements are simple:

1) There are 10 categories(subjects).

2) Select 8 random questions from each category and display them one by one.

3) Get the students input.

4) Calculate the result and display it.

Now, the problem that i face is how to make the script as efficient as possible. Efficient in the sense, make less database hits. I want to store the 80 answers for that particular user in a place and then update them all at once in the DB. I don't want to use cookies. In what way can i achieve that?

Are there any simple php quiz modules that i can refer?

Thanks :)

A: 

If you have to show them one by one, you need to store the results somewhere and since http is stateless you have 2 choices: db or cookie. Now, in my opinion is better to store the answers in a cookie in a var like this

"a:1,b:2,question:answer,.."

and then explode them at the end and check the result.

dierre
i don't want to use cookies because i've validation problems when using it..If i'm using DB then , i think, it's costly..
jest
It shouldn't be costly if normalised and indexed properly
Lizard
I don't know: sessions?
dierre
You can store the questions in `session` (which is stored server side, as you know). If you choose the cookie make sure you crypt the data stored there (I know I tried to break all school systems) and cookie would be my second option (after checking the html to see if one of the answer has a particular "mark"); uncrypted data in a cookie is like going to Johannesburg now (during the World Cup) with a huge sign "I have $1,000,000 in my pockets. Steal it from me, please!"
Bogdan Constantinescu
yeah..even thatz what bothering me
jest
Do you have a real problem in designing it? I mean, in my opinion if talking about cost in db query, then scalability could be solved doing caching but maybe you want to do something in the hardware sector because maybe a single server can't manage so many clients. I mean should analyze a real scenario and find a solution. You're too abstract rigth now.
dierre
A: 

You should not want that. It is perfectly normal for a webapp to store intermediate results in a database. Most apps do several database queries per page.

You could use sessions. This allows you to store data which is coupled to a user. However, session data is also stored somewhere, so efficiency is not a reason to store it in a session instead of a database.

Sjoerd
If not for few hundred students taking tests, what happens when thousands of students login and take up the test. Won't that hinder DB performance? I want to make use of the small resource available as useful as possible.
jest
In-memory shared cache is a viable answer to such a performance problem, but I strongly suspect that this user doesn't actually have that sort of problem yet.
Kalium
Create your program. Test the performance. Determine hotspots through profiling. Optimize those hotspots. Generally, it is very hard to predict what part of a system is the bottleneck, and optimizing prematurely does more damage than it does good.
Sjoerd
+1  A: 

You clearly want a fast cache layer. I suggest either memcached or APC for that purpose. Session data may also work.

That said, you'd probably be better off using a full-stack PHP framework for this. A good one will manage caches for you. I suggest looking into symfony or CakePHP.

Here's the real question, though: are you trying to address this problem up-front before you have established that there actually is a problem? This is a bad approach. Make sure you have a problem before you try to solve it.

Kalium
hmmm..kinda yes. But I don't want to do a re-work after finishing all the modules.
jest
Kinda yes what? Are you *actually* running into the database performance problem you posit or aren't you? Until you're actually running into a performance problem that can't be addressed via server-side configuration *then* you should add a caching layer. Adding unneeded complexity up front is really a bad idea.tl;dr: Don't solve problems before you know you actually have them. Doing so only creates more problems.
Kalium
+1 for the "real question". If you design your application properly, improving performance will not require that much work especially if you use a good framework. Always measure before optimizing, otherwise you may be optimizing the wrong thing or wrong reason (eg. no problem to begin with). It's possible your DB server is really fast but you don't know it :)
Jani Hartikainen
Here's a brief example you can draw from when designing your quiz schema: http://stackoverflow.com/questions/429468/schema-design-for-when-users-can-define-fields/429577#429577
micahwittman
+2  A: 

From my personal point of view, if I'd be asked to design something similar, I would do the following:

  • If I don't want to use database resources I'd have a "before starting quizz" step where I'd fetch my questions from the database
  • Each user (even if not registered) has a unique session; the data fetched from the database would sit right there on the session (and because session is stored server side I wouldn't care for encrypting it)
  • Session it's a bit problematic, though, but using the cookie and encrypting the data seems more work rather than making a longer session (maybe the students need some time to solve the quizz and a 5minute session would be a little low, but that's not a big problem, you can set it as you wish
  • The answers are also stored on the session, at the end you just need to compare the results in the session with the answers in the session which is a pretty basic task: if the results are stored in a separate array, you could just call in_array() on each answer (the array being the correct results) and increment a variable to know how many questions are answered right (that works if every question has the same "value")

Enjoy!

Bogdan Constantinescu
A: 

What you want to do is a sort of wizard-style flow, with a Next button on each page. This is common to store the results in session for such things.

If you store the questions extracted randomly in session, like this :

$_SESSION['questions'] = array(
    array(
        'question'    => 'What is the response to life ?', 
        'answer'      => '42', 
        'user_answer' => null,   // Will contain the user answer
        'answered'    => false), // Will be set to true once the question is answered
    array(
        'question'    => 'What is the color of the sky ?',
        'answer'      => 'blue',
        'user_answer' => null, 
        'answered'    => false)
);

Then you could iterate over the questions, keeping trace of the answered questions.

mexique1