How would a database structure for a quiz look like? [closed] - php

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Here's how my current quiz database structure looks like:
For the sake of testing and simplicity, I've put up only 3 questions.
This is how my table (quiz) looks like:
| id | score | q1_answered | q2_answered | q3_answered |
--------------------------------------------------------
| 1 | 210 | 0 | 1 | 0 |
| 9 | 380 | 1 | 0 | 1 |
| 5 | 210 | 1 | 1 | 1 |
--------------------------------------------------------
Each question column has numbers from 0 to 1, 0 indicating is hasn't been answered and 1 indicating it has been answered correctly.
I was wondering if any of you have another idea of creating a better structure or better, efficient.
Is there also an efficient way to add a timestamp for a user who has solved a specific question?
Say for example: If a user answers question 1, the time of answer will be recorded and will be displayed.
This structure could work but I always thought it might not be efficient if I were to add say 50 more questions.
Any help would be appreciated.

I would create two tables based on the table you have:
scores
sID score testID
1 210 1
9 380 1
// etc etc
quests
sID testID question answer anstime
1 1 1 0 1231237128961
1 1 2 1 1231237128964
1 1 3 0 1231237128968
9 1 1 1 1231237128961
9 1 2 0 1231237128968
Basically, you are normalizing your data in a way that you can easily add more questions without the need to modify the table in any way, you still have a nice clean table where you keep scores that is easy to join
You can also then do much more interesting queries, like How many people answered question 3 at a certain time, aggregate the data nicely and of course, still join it back to the scores if you want to display all the results for a particular ID.
I have also added two columns in the tables called testID. This way, you are able to track not only multiple users for one test, but multiple users across multiple test. you will be able to see whether a student is improving over the course of tests or progressively getting worse as the subject carries on.
Edit: To copy data from your structure will be a bit annoying, but this should get you started on the path at least:
insert into quests (sID, question, answer)
select sID, testID, q1_answered from yourTableName
You can insert the data into the new structure by using a select statement on your original tables like I showed you above.

In a nutshell, you define one table for the questions and one for the answers given by users:
Questions:
QuestionID, QuestionName, ...
Answers:
AnswerID, UserID, QuestionID, AnswerGiven, AnswerCorrect, DateAnswered
This way if you add a new question, you don't have to change the table structure.

I wouldn't worry about efficiency with 50 questions. Just have some fun programming. Try things out. If you have a million questions, or hundreds of thousands of questions you might start to think about efficiency. Computers are really fast.

Related

Is there a way to count repeated strings in records from a MySQL Table? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
I want to know if there is a way to count repeated strings in diferent records in a MySQL table, for instance, given a table like this one:
+----+-----------------------+
| id | data |
+----+-----------------------+
| 1 | this is here |
+----+-----------------------+
| 2 | this would be nice |
+----+-----------------------+
| 3 | this was here |
+----+-----------------------+
| 4 | this needs to be said |
+----+-----------------------+
I'd like the following result:
Count: this(4), here(2)
This is what I've been looking for, but no luck until now.
You can start with this:
SELECT id, data, SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',x.x),' ',-1) as Y
FROM test
CROSS JOIN (select 1 as x union select 2 union select 3 union select 4) x
ORDER BY id, x.x
see: DBFIDDLE
output:
id
data
Y
1
this is here
this
1
this is here
is
1
this is here
here
1
this is here
here
2
this would be nice
this
2
this would be nice
would
2
this would be nice
be
2
this would be nice
nice
3
this was here
this
3
this was here
was
3
this was here
here
3
this was here
here
4
this needs to be said
this
4
this needs to be said
needs
4
this needs to be said
to
4
this needs to be said
be
Things left to be done:
Check If you have more, of less than, 4 words. Currently when you only have 3 word the last word is repeated, and when having more than 5 words they are ignored.
Count the stuff, but that is basic SQL stuff using count(*)
BONUS: Getting the number of words in a string:
SELECT
id,
data,
length(data)-length(replace(data,' ',''))+1 as NrOfWords
from test;
output:
id
data
NrOfWords
1
this is here
3
2
this would be nice
4
3
this was here
3
4
this needs to be said
5

Delete and Insert vs Update rows on table [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I have a web form in when the user can select many available items (idFamilia) for a single Provider (idProveedor) that looks like this
The values are saved in this table
-----------------------------
| idProveedor | idFamilia |
-----------------------------
| 5 | 1 |
-----------------------------
| 5 | 2 |
-----------------------------
| 6 | 2 |
-----------------------------
After a Provider is created, it can be edited and the values selected for idFamilia can be changed. So I have three different scenarios of what could happen:
The numbers of rows remain the same and I would only need to edit the values of idFamilia.
Some items were deleted from the selection and I would need to search the values on the table and delete those rows.
New items are added and I would need to insert those additional values.
Right now I am thinking about just deleting all the rows with the idProveedor that is being edited and just insert the new selection.
Is this a good practice? Will this affect the performance on the long run?
Could you recommend a tutorial or example to do it the other way?
I always go the way to delete and re-create them.
While this adds some performance penalty, it keeps the code simple to understand and easy to maintain. Unless you're Uber, Google, Facebook, Amazon, or other world scale app, the benefits you'd get from optimizing this are much smaller than the cost it incurs: in development, debugging and maintenance time.

Database for Poll + Explanation which can be updated

I've got the following poll form for my users but I am not sure how I should structure the DB around it.
The user will get 20-30 poll questions like the following:
What is your favorite color?
Blue
Green
Yellow
Red
Other
Will be able to choose one of the above answers and must also provide around 100 words explaining why he chose that answer.
I've currently got two tables. One that holds the poll questions and one that holds the poll options. What I am not sure about is how should I hold the user answers.
The thing is because the poll is so big, the user can do it partially, come back at a later time, alter his answers and keep going until he is 100% done which is then that I'll be able to view the whole result in my panel. So he can basically save his progress and alter it at anytime. On top of that I would like to "remove" the whole poll for a specific user and be able to redo it all over again but at the same time keep a history of his previous answers.
So I am not sure if a table like this would be the best option for my needs:
id
user_id
poll_questiond
poll_answer
poll_text
last_update
status
Seems like something like this will create a huge mess. Is there a better way to do this?
I would create 3 tables:
table_polls
+----+---------------------+--------+
| id | description | status |
+----+---------------------+--------+
| 1 | Example description | 1 |
+----+---------------------+--------+
table_poll_options
+----+---------+-------------+
| id | poll_id | description |
+----+---------+-------------+
| 1 | 1 | Question 1 |
| 2 | 1 | Question 2 |
+----+---------+-------------+
table_poll_answers
+----+-----------+---------+----------------+---------------------+
| id | option_id | user_id | description | created_at |
+----+-----------+---------+----------------+---------------------+
| 1 | 1 | 1 | A valid reason | 1970-01-01 00:00:00 |
| 1 | 2 | 2 | Another reason | 1970-01-01 00:00:00 |
+----+-----------+---------+----------------+---------------------+
To recapitulate the above:
A poll has many questions.
A poll question has many answers
A poll answer has one user.
This way you have everything split up with pivot tables and you no longer need to create messy rows in your poll table.
You can expand on the tables of course, if you need extra information for dates etc.
I think you will find it easier if you define your problem domain in semi-structured language. You may decide to delegate some of the logic to the application layer, rather than embedding in the database schema - for instance, saving partially-completed polls might be easier within the application layer.
You might start with something like this, capturing the major entities in your domain, and their relationships, but not their attributes.
The system consists of many polls.
One poll has many questions. A question belongs to 1
poll.
A question can be of type multiple choice (select one) or
multiple choice (select n) or free text
A question may be mandatory or optional
A multiple choice question has 1..n answer options
A question has a sequential relationship to other questions
(e.g. the free text question must follow the favourite colour
question)
The system consists of many users
A user answers many polls
When the user answers a poll, they answer 0..n questions
When the user answers a poll, the answer is only valid if the
user completes all mandatory questions
This suggests that you have two polymorphic entities - question (which can be free text or multiple choice), and answer (as the answer is related to the question, it is also free text or multiple choice).
You have to decide how to model this in your schema - Stack Overflow has many questions on this topic - but I'll pick the simplest.
Poll
-----
Poll_id
Question
------
Question_id
Poll_id
Sequence
Is_mandatory
Description
Question_option
-------------
Question_option_id
Question_id
Option_id
Sequence
Description
User
-----
User_id
Poll_session
------
Poll_session_id
User_id
Poll_id
Date
Status
Poll_session_answer
-----
Poll_session_id
Quesion_id
Free_text_answer
Question_option_id_answer

PHP questionnaire calculation design

So I need an opinion / a way of solution on the matter below.
There is this questionnaire which has 67 questions, coded with PHP and uses a database (MySQL). By design the data table is as follows, where it contains ID and question numbers.
So,
I will generate a report with these answers. i.e. I'll get the mean, median for each question and show them on a user report screen. There are 493 rows now and want to think something which will not get longer and longer to process in time.
Any opinions or an approach which makes the process easier(bearable)? Shall I create a class for the calculations and run for each questions and store the values on a view? Found an answer here for a similar issue but just could not make sure. Really would love to hear any ideas.
Personally, I'd avoid using a table 67 columns wide, and do a 3-column table with a two-column Primary-key instead.
ID | Q | Result
1 | 1 | 1
1 | 2 | 3
1 | 3 | 2
...
4 | 5 | 4
Then run stats on that; it'll be 67 times longer, but your stats will be all be primary-key lookups. And anything less than a couple million rows will be pretty damned fast anyway.
Oh, and do the stats using mysql, it's good at that sort of thing. For example:
SELECT AVG(Result) WHERE Q = 1;
And use this solution for the median.

Best SIMPLE database structure for my web app with resources, categories, and tags [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have been teaching myself to code for about 6 months now and am building my 1st web app for practice.
I'm aiming to build my own very simple cms to store my resources in the database and serve them back up on the page.
I will have resources -
each resource will be assigned to only 1 of 3 categories -
each resource can have multiple tags.
Ultimately the user can navigate to each category page and on that page filter the resources by tag.
I am struggling with how to design the DB.
Without a doubt I will have a resources table.
Should I store the category assignment directly in this table (since each resource can only have 1) or is it better to create a relationship with a category table for this? I've done a lot of research on tag schema's and some seem a bit too complicated for me at this beginner stage. What is the simplest way to store multiple tags for a resource. 2 tables? How would this be accomplished?
I am using PHP and mySQL.
For the category, since you have only one per resource, store on the same table. This is a one to one relationship.
For tagging, you might need two additional tables because this is a many to many relationship (each resource can have multiple tags and each tag can be assigned to multiple resources). One table is to store the tag name and its ID. Another table is to store the relations. This one has two columns, one for the tag ID and other for the resource ID.
Quick example:
id | resource | category
---+----------+----------
1 | rice | 24
2 | apple | 42
id | tag
---+-------
1 | fruit
2 | cereal
3 | food
id_t | id_p
-----+------
2 | 1
1 | 2
3 | 1
3 | 2
Then you can query the tables and JOIN them to get the desired results.

Categories