Storing single form table questions in 1 or multiple tables

蓝咒 提交于 2021-01-28 21:17:35

问题


I have been coding ASP.NET forms inside web applications for a long time now. Generally most web apps have a user that logs in, picks a form to fill out and answers questions so your table looks like this

Table: tblInspectionForm
Fields:
inspectionformid (either autoint or guid)
userid (user ID who entered it)
datestamp (added, modified, whatever)
Question1Answer: boolean (maybe a yes/no)
Question2Answer: int (maybe foreign key for sub table 1 with dropdown values)
Question3Answer: int (foreign key for sub table 2 with dropdown values)

If I'm not mistaken it meets both 2nd and 3rd normal forms. You're not storing user names in the tables, just the ID's. You aren't storing the dropdown or "yes/no" values in Q-3, just ID's of other tables.

However, IF all the questions are exactly the same data type (assume there's no Q1 or Q1 is also an int), which link to the exact same foreign key (e.g. a form that has 20 questions, all on a 1-10 scale or have the same answers to chose from), would it be better to do something like this?

so .. Table: tblInspectionForm
userid (user ID who entered it)
datestamp (added, modified, whatever)
... and that's it for table 1 .. then

Table2: tblInspectionAnswers
inspectionformid (composite key that links back to table1 record)
userid (composite key that links back to table1 record)
datastamp  (composite key that links back to table1 record)
QuestionIDNumber: int (question 1, question 2, question3)
QuestionAnswer: int (foreign key)

This wouldn't just apply to forms that only have the same types of answers for a single form. Maybe your form has 10 of these 1-10 ratings (int), 10 boolean-valued questions, and then 10 freeform.. You could break it into three tables.

The disadvantage would be that when you save the form, you're making 1 call for every question on your form. The upside is, if you have a lot of nightly integrations or replications that pull your data, if you decide to add a new question, you don't have to manually modify any replications to reporting data sources or anything else that's been designed to read/query your form data. If you originally had 20 questions and you deploy a change to your app that adds a 21st, it will automatically get pulled into any outside replications, data sources, reporting that queries this data. Another advantage is that if you have a REALLY LONG (this happens a lot maybe in the real estate industry when you have inspection forms with 100's of questions that go beyond the 8k limit for a table row) you won't end up running into problems.

Would this kind of scenario ever been the preferred way of saving form data?


回答1:


As a rule of thumb, whenever you see a set of columns with numbers in their names, you know the database is poorly designed.
What you want to do in most cases is have a table for the form / questionnaire, a table for the questions, a table for the potential answers (for multiple-choice questions), and a table for answers that the user chooses.
You might also need a table for question type (i.e free-text, multiple-choice, yes/no). Basically, the schema should look like this:

create table Forms
(
    id int identity(1,1) not null primary key,
    name varchar(100) not null, -- with a unique index
    -- other form related fields here
)
create table QuestionTypes
(
    id int identity(1,1) not null primary key,
    name varchar(100) not null, -- with a unique index
)

create table Questions
(
    id int identity(1,1) not null primary key,
    form_id int not null foreign key references Forms(id),
    type_id int not null foreign key references QuestionTypes(id),
    content varchar(1000)
)

create table Answers
(
    id int identity(1,1) not null primary key,
    question_id int not null foreign key references Questions(id),
    content varchar(1000)
    -- For quizez, unremark the next row:
    -- isCorrect bit not null
)

create table Results
{
    id int identity(1,1) not null primary key,
    form_id int not null foreign key references Forms(id)
    -- in case only registered users can fill the form, unremark the next row
    --user_id int not null foreign key references Users(id), 
}

create table UserAnswers
(
    result_id int not null foreign key references Results(id), 
    question_id int not null foreign key references Questions(id), 
    answer_id int not null foreign key references Answers(id),
    content varchar(1000) null -- for free text questions
)

This design will require a few joins when generating the forms (and if you have multiple forms per application, you just add an application table that the form can reference), and a few joins to get the results, but it's the best dynamic forms database design I know.




回答2:


I'm not sure whether it's "preferred" but I have certainly seen that format used commercially.

You could potentially make the secondary table more flexible with multiple answer columns (answer_int, answer_varchar, answer_datetime), and assign a question value that you can relate to get the answer from the right column.

So if q_var = 2 you know to look in answer_varchar, whereas q_value=1 you know is an int and requires a lookup (the name of which could also be specified with the question and stored in a column).

I use an application at the moment which splits answers into combobox, textfield, numeric, date etc in this fashion. The application actually uses a JSON form which splits out the data as it saves into the separate columns. It's a bit flawed as it saves JSON into these columns but the principle can work.




回答3:


You could go with a single identity field for the parent table key that the child table would reference.



来源:https://stackoverflow.com/questions/54443868/storing-single-form-table-questions-in-1-or-multiple-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!