Surveys and Answers, relation on many-to-many - mysql

I have the following database scheme (I don't know if it's perfect but I think it's allright?)
It's a system where a User has many Surveys, the Users provide Answers for Questions in the Survey_Answers table.
Now a User can have multiple Surveys, it's the same questions but in a later time of the year they have to fill in the survey again.
I'm nearly there, I'm just wondering how to connect the answers to the survey. Should I make a relation between survey_answers and user_surveys.. thus adding an id to the user_surveys table
Or do you think it's ok to make a relation to the surveys table? I'm not sure which one is correct.
I outlined the 2 possibilities in the second screenshot.
Looking forward to your responses!
Thank you.

This probably depends on how your system is most likely/most frequently going to navigate the relationship.
If you are more likely to be looking at a Users answers and saying - hey let me see when this question was answered, as part of which dated survey, then you should join on user_surveys (I am assuming that the employee_id you are storing would match the user_id in user_surveys)
If you're more likely to be looking at a Users answers and saying - hey what survey did this question belong to, then you should join on Surveys.
You can still answer either question whichever join you use, it will just be a matter of more optimal performance (fewer table joins when trying to answer the most common query).
In reality there probably isn't much in it, so you could always toss a coin :)

Related

Suggestions on Database Design

I am building a sample online examination platform (I'm in the process of learning Ruby on Rails) with the following specifications:
There are 1000 different multiple choice questions.
Each question can have up to 5 possible answers, 1 of them is correct.
A user is presented with 10 random questions at a time (let's call this a test). If a user answers a question correctly 2 times, then this question will not be shown to him again.
A user passes the exam if he has answered every question correctly 2 times, in other words when there are no more questions left to show to him.
A first try :
student
-student_id
-name
question
-question_id
-text
option
-option_id
-text
-is_correct
-question_id
student_answer
-student_id
-question_id
-option_id
Although we could only store the correct questions, I've decided to include the 'option_id' in the student_answer table in case I need to display statistics (hardest question etc) in the future.
So up to this point, a question has many options, every option belongs to a single question and every time a student answers a question a student_answer row is created.
It seems to me that this approach would have some performance issues since for each test we'd have to select all the answers given by the user, group them by the question_id, for each question calculate the correct times it has been answered, get a set of question_id that shouldn't be displayed and finally select 10 random questions out of the 1000 initial ones minus those we just excluded.
Another thought I had was to have a JSON array in the form of {[0,0,1,...,1]} for every user. Each cell would be the number of correct answers for the question with an id matching the array index but I find that a bad idea.
Since I'm relatively a beginner when it comes to database design I'd like some feedback on my approach. Please feel free to suggest ways that are completely different than the above.
Thank you very much.
I think you may need to include the question_id in the option table.
One approach would be to move some of the processing into Ruby.
Select the 1000 questions.
Select the answers given by the user: SELECT count(*) counter, question_id, option_id FROM student_answer JOIN option USING (question_id,option_id) WHERE student_id=x AND option.is_correct=1 GROUP BY question_id,option_id HAVING counter>1
Randomize the 1000 questions in ruby, iterate though them, and exclude any that were found in your query of correct answers for this student. Stop after 10 questions.
If only one answer can be correct, then why store the correctness in the option table, the question record should contain the foreign key of the correct answer.
You describe some entities not addresed by your design. You maybe don't need to store 'a test' but this, and a primary key on student_answer makes for a model which makes it a bit easier to answer different questions about the data.
I think you have a good approach going, I would probably do the same. - symcbean does make a good point above, but my solution for this would be to store a boolean column within the student_answer table for whether the answer is correct.

Reusable Questions in MySQL Survey Design

I'm working on a Reusable Survey database design. So the idea is.
A Client has many users, A client has categories which consist of questions. Every User has to answer all questions to complete the Survey. Those answers are stored in the Answers table.
The hard part
Some users are coaches, so a coach can fill in the survey for the user, thus providing a score on what they would answer in the place of the user. So we can later compare what the user answered and what the coach answered for each user. That's not to hard! The following is:
After some months we should be able to let the users redo the surveys, so with new answers to all the still existing questions.
I'm wondering if my db design is allright for this.
I have the feeling that this isn't optimal.
For example the following queries seem difficult with my design
For a given Scan, give me all categories and questions
(because of the many tables in between)
Looking very forward to your responses!
Think about how you are going to want to use this information. Are you going to want to compare users scores to coaches scores to their new scores? I think that is likely. Will they end up taking the survey multiple times if they don't improve enough? Are there going to be questions that do not have integer answers? How are you going to store those results? When they create a new survey are they going to want to reuse some previous questions or answers (like yes/no). How are you going to identify a unique user, names are not unique and autogenerated IDs are unique, but how will you know which John Smith belongs to which of the 12 ids you have?
I would rename the Answer table as SurveyResponse.
To it I would add the datetime of the surveyresponse (so people can
answer it multiple times and you can compare the answers) and a
Survey ID (from the new table in the next suggestion).
I would create a Survey table that stores the questions that belong
to a particular survey.
I would create a new Answer table that just has possible answers and
an ID.
I would create a table called SurveyQuestionAnswer which stores the
allowed answers to the question for each survey (different surveys
might have different possible responses to the same question).

Creating a Poll application. Need advice on database structure for the vote count

I'm writing an application to allow users to create a Poll. They ask a question and set n number of predefined answers to the question. Other users can vote on the answers provided for that question.
Current structure
I have designed the database like this:
Storing the vote count
Current thinking is, I create a new column called vote_count on the link table and every time that answer gets voted, it updates the record.
This works. But is it right? I'm new to database systems, so I can't imagine I'm doing much right. What are some more efficient ways to achieve this?
As far as it goes yes that's OK. However these tables will be incomplete. When your second quiz is created, you'll have to extend the QUESTIONS table. If this second quiz's Q1 also has a yes/no answer, you're going to have to extend the LINK/VOTES table.
You also have to think about how it's going to be queried and design indexes to support those queries.
Cheers -

One or two tables for forum?

Im building a forum and I'm wondering whether I should have one table where I store all main posts and then all the answers in another table.
I've always stored everything in one table, making it east to count and let users comment every post (comments in another table).
What should I do? Pros and cons? Tried to google but didn't find anything.
Thanks for your help!
I usually follow the rule every type of dataset gets a own table. This way you can cleanly define relationships
You have types like
userTypes (e.g. guest,user,mod,admin)
users (has one userType_id)
posts (has one user_id)
answers (has one post_id)
comments (has one post_id, has one answer_id)
Since comments can be added for both, a post and an answer, you could add two bridge tables to define this relationship.
comment_to_answer (has one comment_id, has one answer_id)
comment_to_question (has one comment_id, has one question_id)
In case you save both, posts and answers into one table, posts table would need to reference themselves to define the posts - answers one-to-many relationship, which would make querying more complicated.
If you want to be able to cascade, post can have an answer, answer can have an answer and so on, you probably go better with one posts table and a parent_id pointing at the id of posts
Hope this helps.
This is highly subjective, given that it depends on your needs and intentions. Let me explain...
Forums, such as they are, usually take one of two forms. They are sometimes in the form of a main post, with subsequent comments. The main post, therefore logically would live in one table, and the comments in another. Facebook and Stack Exchange sites are examples of this.
In other cases, the content may take the form of a list of comments. More traditional forums take this form. In the case where hierarchy is called for, rather than pure date ordering, the single table approach makes more sense.
In both cases, hierarchy can be dealt with by creating a parent and child column.
My personal preference would be to go with one table, unless the main post contains an order of additional data that isn't needed for comments. That's just an efficiency thing, but you definitely don't want thousands or millions of rows with NULLs that take up space to no avail. To distinguish a post from a comment you can employ any number of logical schemes such as distinct ID's or flag columns.
Ultimately, an architectural situation like this depends on the project in question. There are advantages and disadvantages to both approaches. Using multiple tables offers a little more in the way of 'future proofing' your project in the case where complexity is added at a later date.
Well - since one post can have multiple answers I would go for a separate table.
Pro:
Less redundant information
Answer can be updated/deleted independent from the post
Easier counting of questions / answers
Con
Non (well, perhaps that you need to join the tables for certain queries, but hey that does not really count)
Same reason why you have comments already in another table...

Simple survey database design

I'm creating a survey for visitors of my event.
However it's been a while since I created a database. So I need some help.
I found some solutions but they are way to extensive and that is something I don't need.
Visitors need to stay anonymous but they can leave their email behind (seperate table Emails that isn't linked to anything atm).
They have about 20 questions, some are open, some are one option(radio) and some are multiple options (checkboxes).
The questions need to be reusable.
That's about it.
I just don't know how to go beyond the many-to-many in the diagram you see below.
How do I go from here? An Answers table needs to have a relationship with? The Surveys_have_Questions, or with Questions?
Edit:
As the answer in the following links mentions, most surveys are based upon classic design patterns. Mine is one of those surveys. More info in the link below:
What mysql database tables and relationships would support a Q&A survey with conditional questions?
I would probably model the event of a user taking a survey, perhaps a table called "User_Answer_Session", which has links to the survey and the user; and then "User_Answers", which are tied to the session and the question and include the actual blob of the answer. How exactly I modeled the answers would depend on a few things (mainly how robustly I wanted to be able to look them up). For instance, do I want to be able to index multiple-choice answers for extremely rapid reporting? If so, then you need to model for that. This may include creating a "Question_Options" table, which is a one-to-many between a question and the available options...
This should get you thinking along a good path. :-)
well i dont see reason why you need all these tables ! i think it can be much simpler than that.
surverys
desc VarChar
startDate timestamp
endDate timestamp
isOpen boolean
survery_questions
survery_id int (FK)
question Text
vote_count unsigned INT
user_survery
user_id
survery_id
unique key (user_id_survery_id) #to ensure no duplicate votes
That all :).
when ever a user vote just run
insert into user_survery (user_id,survery_id) VALUES (1,1);
update survery_questions set vote_count = vote_count+1;
when u need to get a survery result
select * from survery_questions where survery_id = X;
etc.