What would be the best way to store questions and answers for a survey, where do I need to at least save traffic to the database?

Background
I am writing a survey that is going to a large audience. It contains 15 questions, and there are five possible answers to each question along with potential comments.

The user can view all 15 questions, answering them in any order, and is allowed to leave the survey at any time and return to answer the remaining questions.

After answering all 15 questions, a submit button appears, which allows them to send questions as final answers. Prior to this step, all responses should be restored when the user loads the survey page.

The requirement is that the user sees only one question on the page, and the Previous and Next buttons allow the user to scroll through the questions.

Demand
I can ask this question every time the user clicks the button and saves the current answer and so on, but this will be a large number of calls to the database, which is already heavily used. I don’t have time to buy a new server, etc. Therefore, I have to do what I have. Is there a way to cache questions on the user's machine and / or answers? Obviously, I need the response data to be safe and only known to the user, so I feel a little stuck as the best way to do this. Any pointers?

I am ready to offer a generosity of 100 points on this subject, if it means that I get a good discussion of quality and feedback.

+7
sql-server
source share
9 answers

You have three requirements that need to be balanced:

  • users should be able to return to their survey at any time
  • responses entered by users should be stored with the least likelihood of data loss.
  • you need to minimize getting into the database.

Any solution that includes caching responses in a volatile place (cookies, session, etc.) increases the risk of data loss. The final decision depends on how you evaluate the three requirements by importance. If the problem with db is at the top, you will either have to risk data loss or spend a lot of extra time coding the solution using some temporary storage scheme (for example, the idea of ​​a Kevin flat file).

Several people have suggested that you prematurely optimize. I suggest you consider this idea first - maybe this whole thing is debatable.

However, assuming your db situation is a real problem, I think your best balance of requirements would be a system that immediately saves the db response (to prevent data loss), but carefully manages when you really need to hit db.

  • When the application starts (or when the first user requests a survey) it loads the survey and its questions into the application cache. If any of the questions has a list of possible answers, download them as well. You will only need to hit db once during the life of the application (or cache duration) in order to download the polling data.
  • When the user starts the survey, run a single request to load any existing answers (in case they are a returning user) into the object in the session - it can be as simple as a <List>string . (If you can somehow define a new user without getting into db, then you can skip this step for new users.)
  • Use the session response object along with the survey question object in the application cache to populate each page without pressing db again.
  • When a user submits a response, compare it with the session response object to see if it has changed (it can simply click "next" on the page with the previously entered answer). If the answer is new or changed, save it in db and in the session response object.
  • When the user leaves the survey, you do not need to do anything - everything is already saved.

With this scheme, you press dB once to download the survey, once for each user when they start (or restart) the survey, and once for each new or changed answer. This is probably not so much a reduction as you hoped, but it gives you better data protection.

+1
source share

If there is no reason to use a database, you can always save the results in flat files on the server itself. This is not like the data you are storing is relational. Worst of all is worst, you can always insert them back into relational db as a batch job every night.

Another option would be the application cache. However, if your web server crashes suddenly on you, you risk losing information from there.

You can also store values ​​in user cookies.

+2
source share

Based on my personal experience (serving thousands of short survey pages per second), I suspect that your concerns are unfounded. Among other reasons, the DBMS will cache such small amounts of data much more efficiently than you can.

I tested this by loading questions and answers into the Application-scope collection at startup and afterwards serving them from memory - often it didn't make any difference.

Your alternative is to immediately send the browser to the browser and write it as a javascript application that stores data in (encrypted) cookies and only hitting the database when all this is done. It is tiring, but not difficult.

+2
source share

If database problems are a problem, you can cache them on the web server (or wherever you are), but it looks like every answer should be recorded when the user proceeds to the next question.

If the questions and possible answers are the same for everyone, I will definitely cache them at the application level - this can be stored in the Application object. In any case, you could optimize the database calls to return the results as efficiently as possible - i.e. Multiple result sets or a combined result set from a single saved process. If you don't mind multiple copies for each session (or if there are options), you can save them in a Session object. Storing it on the client (i.e., Cookies) is not really safe and pointless due to the preservation of the bandwidth of the client web server.

This is very similar to premature optimization for me.

+1
source share

This is a classic issue with maintaining state between pages in a browser-based system. I also assume that we want this data to be saved even if the user logs out and comes back later. Here are the options:

  • With a high-availability server, we can store one set of 15 responses in memory (not a session) for this user (perhaps not a good idea and it is not easy to balance the load)
  • We denormalize 15 responses to 1 row of sql table
  • We store data on the client using a cookie or localStorage (IE8).

I feel that the first two options are probably not what you are looking for, so let's look at the last option.

You could just store the answers in a cookie. There is a small chance that this might get lost and that the user may log in from another machine, but this may be an acceptable risk. With the latest browsers that support HTML5 (including IE8 afaik), you get the advantage of localStorage, which is not as easy to delete as a cookie. You can return to cookies if it was not available.

Cookies can be encrypted if required.

+1
source share

Not sure which languages ​​you use, but most of them have an application cache. I would save the questions there and retrieve them from the database and save them when they are not in the cache (when the application is being processed).

As for the answers, are users registering in some way? Is it possible to store answers in a cookie until all the questions are answered?

Edit: If cookies are not reliable enough, you can save (in the application cache) a list of requests (inserts / updates) that must be executed, they will not be executed until the request limit is reached or under certain conditions (i.e. e. execute the list of requests when the user asks for the answers that are in the list, the execution list when reusing the application, etc.).

Pretty crude, but you get it:

 if (function == "get question" && userQuestionIsInQueue) || function == "finish survey" execute(Application["querylist"]); continue as normal... if function == "submit answer" if Application["querylist"] == null Application["querylist"] = newAnswerQuery; else Application["querylist"] += newAnswerQuery; 

You also need to add execute (Application ["querylist"]) to the recycle event, I believe you can hook it in global.asax

Edit 2: I would also accumulate all the database transactions for the query in 1 if you needed to execute a list and then get a response for the user, make them in one transaction and save the trip. Common practice for optimization.

+1
source share

Your script is an ideal candidate for predictive extraction pattern . I would advise you to remove all your questions. When a user subscribes using a template to extract the first 5 answers (if they gave any answers) and based on their navigation (where is their current question), get the information from the Response object or from the database.

NTN

+1
source share

I would like to offer you a new HTML5 feature called Dom Storage, but since only new browsers support it, this may be the problem currently using it.

With DOM Storage, you can store data in the user's browser. Since it can store up to 5 MB per domain in Mozilla Firefox [3], Google Chrome and Opera, 10 MB per storage area in Internet Explorer, you can store answers and question IDs in the DOM repository.

Even when using DOM Storage, not to mention hitting the database, you can also reduce the number of calls to the server.

Since we all know that work with cookies sometimes happens, and it can store 4kb, the easiest way is to store information about the key value in the DOM repository.

You can store key value information specifically for sessions, as well as locally. At the end of the session, the session information will be deleted from the browser, but if you save the local values, even the user closes the tab, the key value will remain for a while.

Code example:

 <p> You have viewed this page <span id="count">an untold number of</span> time(s). </p> <script> var storage = window.localStorage; if (!storage.pageLoadCount) storage.pageLoadCount = 0; storage.pageLoadCount = parseInt(storage.pageLoadCount, 10) + 1; document.getElementById('count').innerHTML = storage.pageLoadCount; </script> 

You can learn more about the DOM repository from the links below:

+1
source share

Do you mean ... cookie?

0
source share

All Articles