So I have a HTML form where users can answer single-choice questions either by checkboxing one of the three preset responses, or writing a custom answer of their own.
While this is obviously a many-to-many relationship, I still cannot find a proper way to design database tables so as to handle both types (TEXT and BOOLEAN). My current quick-and-dirty solution is to hard-code a specific choice_id in the junction table for custom answers. I'm looking for a better pattern for this.
Have the following tables:
Table 1:Question
QuestionID (ID)
QuestionText (Text)
Table 2: Question Response
QuestionResponseId (ID)
QuestionResponseTypeId (References Question Response Type)
QuestionResponseDetailsId (References Question Response Details) - This should be used for text only values (Custom Answers)
QuestionResponse (Boolean)
Table 3: Question Response Type
QuestionResponseTypeId (Id)
Description (Text) -- Dictates if the answer is a boolean or a text field
Table 4: Question Response Details
QuestionResponseDetailsId (Id)
Description (Text) - Holds the text answer to the questions
When the following tables are populated you will have a structure that holds the question, the response of the question (text or boolean).
You could then filter on this to see only text based answers, for example:
SELECT * FROM QuestionResponse
INNER JOIN QuestionResponseDetails ON QuestionResponse.QuestionResponseDetailsId = QuestionResponseDetails.QuestionResponseDetailsId
WHERE QuestionResponse.QuestionResponseTypeId = 1
Where 1 is a Text based answer and 2 is a Boolean based answer (From the Question Response Type Table)
If I were you, I would do something like this:
Table Answers:
question_id INT(11)
answer_id INT(11)
preset_answer TINYINT(1) //1, 2, 3 for three answers
custom_answer VARCHAR(255)
Related
I'm trying to design MySQL tables for survey.
The survey is composed of 6 sets of questions, 15 questions for each set, so total 90 questions. The questions and the order of questions are not gonna be changed, and there are some possibility for new set of questions(also 15 questions per set) to be added.
They are all 'yes or no' questions so the answers will be saved as true or false in boolean way.
I also save sex, nationality, age of users for statistics.
I wanna get the percentage of the same answers between two users.
I wanna get the percentage of the same answers between one person and majority(majority is the answer of more than 50%).
I wanna get the statistics of yes or no per question by combination of sex, nationality, age. For example, 66% answered yes for question no.11 or 12% of Korean women answered no for question no.86
So I made a table to support all those features
questions table
q_id PK(1 to 90)
q_text VARCHAR(100)
users table
u_id PK
sex TINYINT
nationality VARCHAR(20)
age TINYINT UNSIGNED
q_1 TINYINT
q_2 TINYINT
...
q_90 TINYINT
Is it okay to have 94 columns in one table? I'm afraid the number of columns will increase as I add some questions sets. So I splited answers to set table
set1 table
s_id PK
u_id users_table
q_1 TINYINT
q_2 TINYINT
...
q_15 TINYINT
set2 table
s_id PK
u_id users_key
q_16 TINYINT
q_17 TINYINT
...
q_30 TINYINT
and so on. I now have 6 set tables and I now can add new table if I add new set.
I searched a little about this and I saw that it would be better if I have a separate table for answers
answer table
a_id PK
u_id users_key
q_no question number(1~90)
answer TINYINT
I'm afraid that answers table may grow too big because answers table get 90 rows per user.
I'm really not sure which design is better. I've searched stackoverflow for answers but I couldn't find appropriate answer for yes or no survey.
Creating all those columns q_x is crazy, you just need to create a table called question_set with all the question like :
s_id PK
s_type (you can put 1, 2, 3 for set group)
q_id FK(questions)
You should normalize your table, putting all those columns will sooner than later create you problems. In the case you need to denormalize it is better to create views for that.
I would rather use foreign keys to make it more flexible.
So I would create
set_table
set_id PK
set_name Text
question_table
question_id PK
//This will help you put same question in multiple sets
question_set
set FK (set_table)
question FK (question_table)
user_table
user_id PK
user_name Text
sex Text
user_answer_table
user FK(user_table)
question FK(question_table)
answers Bool
Then you can write complex queries with joins to get all the metric you need. This will give you plenty of flexibility to add new questions, sets, users without the need to change the schema.
I'm new to mysql but I am trying to make a quiz website as a pet project in php and store questions and answers in mysql. I want to have multiple choice and true and false questions for now. What would be the best way to do this. Should I create one table or two for the types of question. Any tips on how to write this?
I don't think it is a good idea to use one table.
I would say creating 2 tables will be good. Your question is light compare to what you intend to build. But if I guess right you will want to print result after submit... Then comes the answers table. If you are not using cookies, then "participant" should have a table too methinks.
Goodluck on your project it's a good start.
I would like to propose 3 tables.
1) Table with information about question and its type
2) Table for storing TF and question id
3) table for storing multiple choice options and question id
1) challenge_question table:
id
challenge_id
question (text of the question)
required (some questions will be required to be displayed per each challenge)
question_type (here I indicate what type of question: Mult. choice, T/F)
2) challenge_question_mc (multiple choice)
question_id = FK/PK to challenge_question
option = text of the option
is_correct = Boolean to indicate the answer
3) challenge_question_tf (true or false)
question_id = FK/PK to challenge_question
is_correct = Boolean
If you want both true/false and multiple choice questions (and don't want separate tables for each type of question) you could make the following three tables.
Question:
QuestionId: int unsigned primary key
Text: varchar
Answer:
AnswerId: int unsigned primary key
Text: varchar
QuestionAnswer:
QuestionId: int unsigned
AnswerId: int unsigned
IsCorrect: boolean
When you want to display the possible answers to a question you can JOIN the last two tables:
SELECT Answer.AnswerId, Answer.Text FROM Answer JOIN QuestionAnswer ON
Answer.AnswerId = QuestionAnswer.AnswerId WHERE QuestionId = ?
And if you want to check whether a given answer is correct you can use:
SELECT IsCorrect FROM QuestionAnswer WHERE QuestionId = ? AND AnswerId = ?
which will return 1 for the correct answer and 0 for wrong ones.
You can reuse rows in the Answer table if you don't want to create a new set of e.g. true/false answers for each question. Just make sure to connect questions with possible answers in the QuestionAnswer table and mark the combinations as true or false (1 = true, 0 = false).
If you don't care about reusing possible answers in different questions I guess it would suffice with two tables if you merged Answer and QuestionAnswer into a single table.
You might want some other tables later on if you want to separate the questions to specific quizzes. That could be achieved by making a Quiz table with QuizId and Name:
QuizId: int unsigned primary key
Name: varchar
and another table QuizQuestion where you tie QuizId and QuestionId together:
QuizId: int unsigned
QuestionId: int unsigned
Then you can use JOIN on the tables to get the questions of a specific quiz.
I'm putting together a question and answers application - the answers are only going to exist as long as there is a question that relates to it.
So I've decided not to give the answers table it's own id column and have made the primary key a foreign key that relates to the question_id.
Questions table:
id | title
Answers table:
question_id | title
Should I keep it this way or give the answers table it's own id column?
If there is possibility of multiple answers for a single question then it will be better to have a primary key on answer table too to identify each row uniquely if we get duplicate answers as follows
id | question_id | title
1 1 5
2 1 5
3 2 true
But, in case you are anticipating only a single answer for each question then it is better to merge it to the question table as both question and answer are directly dependent on a single primary key.
id | question | answer
1 quest 1 ? 5
2 quest 2 ? 5
3 quest 3 ? true
4 quest 4 ? null
I hope, this clarifies your doubt.
To expound a bit on the two valuable comments that have been made, in my experience, the following is the most effective set of rules to follow when defining a database schema (I will give reasons after):
Create a Primary Key for each table
Create a surrogate key to be that Primary Key
When you have a one to many relationship (as you do in your questions & answers tables) include the PK from the one table (your questions table) in the many table (your answers table) NOTE: this is exactly as you have done it... except the answers table doesn't have it's own PK & surrogate key
When there is a many to many relationship between two tables create a linkage/join/relationship table which has a one to many relationship to your two tables (meaning you put the Primary Key of each table into the relationship table as a foreign key to the two tables, respectively)
REASONS (in the same order):
Primary key columns guarantee uniqueness for each row within the scope of the table itself (no other database object has to be involved & every row will be required to be unique). They also provide a default index in most databases, which speeds up table scans/queries. As, mentioned this effectively meets first normal form.
I've found surrogate keys to be a powerful & effective way to simplify both database design & relationships between tables. If you aren't familiar please read here: http://en.wikipedia.org/wiki/Surrogate_key
You have done this already, so I'm assuming you understand the benefits.
This is here simply to provide an example of how using surrogate keys as primary keys in every table can help you as a database schema grows. If you need to add other tables in the future you won't have to spend as much time & effort figuring out how to join them you already have all the keys you need to easily create a join table (for instance, if you later add users to the mix... users can be the author of either a question or answer OR both... this could get a little harry if you attempt to associate the SAME value to both the question & answers tables independently... in fact it won't work)
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I am making a table of a products like different types of vehicles: cars, trucks etc. They are made by an array of countries and each country has an array of makers, like Japan has Toyota, Honda, etc and US has Ford, GM etc. Once the database is built, I need to do operations like "select all vehicles made by Toyota".
What is the best way to store that?
The data structure is not necessarily the same as your array structure. The key word is "normalisation": design your tables in a way that avoids redundancies and make sure that each record in a table contains exactly the information that is relevant to describe the subject of that particular table.
A possible structure could be:
create table vehicles(
vid int auto_increment primary key,
void int,
vname nvarchar(32),
vtype int,
vmotor varchar(32), ...)
create table oem (
oid int auto_increment primary key,
oname nvarchar(32),
countryid int, ... )
The column void of table vehicles references the primary key oid of the oem (original equipment manufacturers) table.
A typical query can be the following:
select * from vehicles where
exists (select 1 from oem where oid=void and countryid=7)
countryid is just an integer key referencing yet another table (not listed here) containing country names etc.. Assuming that record 7 of the country table contains 'Japan' then the above query will list all vehicles made in Japan.
Or - coming back to your original example -
select * from vehicles where
exists (select 1 from oem where oid=void and oname='Toyota')
would list all vehicles of that particular manufacturer.
This little example is just the starting point for you to understand `normalisation'. Like Marc B already said: Study the concept for yourself and you will be able to answer your question yourself. Here is another example based link that might be helpful: http://db.grussell.org/section008.html .
Why not just have a table called Automobiles,
and then rows like Car, Model, Company,Country
and then you can just
SELECT * FROM Automobiles WHERE Company = 'Toyota' AND Country = 'Japan'
I have been reviewing the questions and answers here: Recommended SQL database design for tags or tagging ,
and I understand the general design of the database, but how does it work? For instance, say I have the design setup like this:
Table:QuestionsColumns: QuestionID, Title, Content
Table: Tags
Columns: TagID, Title
Table: QuestionTag
Columns: QuestionID, TagID
Now when a user creates a new question, would I insert that question into the Questions table with the QuestionID set to auto increment? Then do the same for the Tags?
But then how do I match the QuestionID to the TagID in the QuestionTag table if I don't necessarily know what the ID is upon insertion?
if it's mysql, the last ID can be traced using MYSQL_INSERT_ID()