Reputation: 523
I am trying to find the best solution for creating a survey application which allows the users to choose their questions within an administrator section.
If I have a front end web page which the questions are asked, and when they answer them, I save the answers in a database. Now this is great if the columns in my "FinishedSurvey" table match the questions. However, what I want is to be able to allow the users to choose their questions so that when they log on, they see their questions and when submitting, those answers are saved alongside those questions for future retrievable.
This question moves into any application where you require people to be allowed to change what is store in a database without you knowing.
I have done things like this in the past where I have say 20 int columns and 20 varchar columns with generic names which a config file maps to a particular customers configuration. Say varCharColumn1 is mapped to "What is your name?". However this is messy, not really expandable, and is wasting storage.
This application will have thousands of users, all asking different questions with different methods of input and different formats of answers. Some may require drop downs with set answers, calendars, free text with 10 characters, free text with 1000 characters, and numbers.
There is probably a simple answer or approach, or even a technology I am not famiular with to do just this, however I can't really think of an easy way.
This particular application is a ASP.NET 4.0 web site with MsSQL database.
Upvotes: 0
Views: 1203
Reputation: 151586
columns [...] match the questions [...] 20 int columns and 20 varchar columns [...] However this is messy, not really expandable, and is wasting storage.
You're right. Pick up a book on database normalization. What if someone wants a survey with a hundred questions? Will you say "We can't", or will you roll out an update that creates a hundred columns?
I think I'd do it like this: say you have a Questionnaire table, at the top level:
ID | Description
-------------------------
1 | 'Test questionnaire'
Create a table consisting of Questions, for example:
ID | QuestionnaireID | Question | ( Other options like 'IsMandatory')
----------------------------------------------------------------------------
1 | 1 | 'Test question' |
Then create an Answers table:
ID | QuestionID | Answer | IsUserSpecified
---------------------------------------------------
1 | 1 | 'Test answer 1' | 0
2 | 1 | 'Test answer 2' | 0
3 | 1 | 'Other...' | 1
Then create a Response table containing answered questions:
ID | UserID | AnswerID | AnswerValue
----------------------------------------------------------------------------
1 | 1 | 1 |
1 | 2 | 3 | 'I was entered by the user'
And you're done. You let users enter an AnswerValue like when they can enter their own value, like the "Other..." answer.
Unfortunately, this does not deal with the typedness of the given answers. I think, but I haven't had the time to think and/or test it through, you can add typed columns to the Answers and Response tables (like VarCharValue
, DateTimeValue
, IntValue
...). You'll then have to register with the Answers table what type of value can be entered for answers and fill/read the appropriate column. That design still smells, though.
Upvotes: 3