Фон
Я пишу обзор, который идет к широкой аудитории. Это содержит 15 вопросов и существует пять возможных ответов на каждый вопрос наряду с потенциальными комментариями.
Пользователь может циклически повториться через все 15 вопросов, ответив на них в любом порядке и разрешен оставить обзор в любой точке и возвратиться для ответа на остающиеся вопросы.
После того как ответ был предпринят по всем 15 вопросам, кнопка отправки появляется, который позволяет им отправлять вопросы как окончательные ответы. До того этапа все ответы требуются, чтобы быть восстановимыми каждый раз, когда пользовательские нагрузки страница обзора.
Требование - то, что пользователь только видит один вопрос на странице, и кнопки 'Previous' и 'Next' позволяют пользователю просматривать вопросы путем прокрутки.
Требование
Я мог запросить вопрос каждый раз, когда пользователь нажимает кнопку, и сохраните текущий ответ и так далее, но это было бы большим количеством хитов к базе данных, которая уже в большой степени используется. У меня нет времени для обеспечения нового сервера и т.д., таким образом, я должен суметь обойтись тем, что я имею. Есть ли какой-либо способ, которым я могу кэшировать вопросы на пользовательской машине и/или ответах? Очевидно, мне нужны данные ответа, чтобы быть безопасным и только известному пользователю, таким образом, я чувствую себя немного застрявшим что касается лучшего способа сделать это. Какие-либо указатели?
Я готов предложить щедрость 100 точек по этому вопросу, если это означает, что я получаю некоторое обсуждение хорошего качества и движение обратной связи.
У вас есть три требования, которые необходимо сбалансировать:
Любое решение, которое включает кеширование ответов в нестабильном месте (файлы cookie, сеанс и т. д.), увеличит риск данных потеря. Окончательное решение зависит от того, насколько важны три требования. Если проблема с базой данных находится наверху, вам придется либо рискнуть потерей данных, либо потратить много дополнительного времени на кодирование решения с использованием какой-либо схемы временного хранения (например, идея плоского файла Кевина).
Несколько человек предположили, что вы можете проводить оптимизацию раньше времени. Я предлагаю вам сначала обдумать эту идею - возможно, все это спорный вопрос.
Однако, если предположить, что ваша ситуация с БД представляет собой реальную проблему, я думаю, что вашим лучшим балансом требований будет система, которая немедленно сохраняет ответ в БД (для предотвращения потери данных), но осторожно управляет, когда вам действительно нужно попасть в БД. .
. (Если вы можете каким-то образом идентифицировать нового пользователя, не нажимая db, вы можете пропустить этот шаг для новых пользователей.) В этой схеме вы нажимаете db один раз, чтобы загрузить опрос, один раз для каждого пользователя, когда они начинают (или перезапускают) опрос, и один раз для каждого нового или измененного ответа. Вероятно, не так много, как вы надеялись, но это дает вам лучшую защиту данных.
Если нет причины использовать базу данных, вы всегда можете сохранить результаты в плоских файлах на самом сервере. Это не похоже на то, что данные, которые вы храните, каким-либо образом относятся к реляционным. В худшем случае вы всегда можете вставить их обратно в реляционную базу данных в качестве пакетного задания каждую ночь.
Другой вариант - кэш приложения.Однако, если ваш веб-сервер внезапно выйдет из строя, вы рискуете потерять информацию оттуда.
Вы также можете сохранить значения в файлах cookie пользователя.
Не уверен, какие языки и т. Д. Вы используете, но у большинства из них есть кеш приложений. Я бы сохранил там вопросы, извлек их из базы данных и сохранил, когда их нет в кеше (когда приложение перезапускается).
Что касается ответов, пользователи как-то заходят в систему? Можно ли сохранять ответы в файле cookie до тех пор, пока не будут даны ответы на все вопросы?
Изменить: Если файлы cookie недостаточно надежны, вы можете сохранить (в кеше приложения) список запросов (вставки / обновления ), они не будут выполняться до тех пор, пока не будет достигнут предел запроса или при определенных условиях (например, выполнить список запросов, когда пользователь запрашивает ответы, которые есть в списке, выполнить список, когда приложение перезапускается, и т. д.).
Довольно грубо, но вы уловили идею:
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;
Вам также нужно добавить execute (Application ["querylist"]) к событию recycle, я думаю, вы можете подключить его к global.asax
Изменить 2: Я бы также суммировал все транзакции базы данных для запроса в 1, если вам нужно было выполнить список, а затем получить ответ для пользователя, выполнить их в той же транзакции и сохранить поездка. Обычная практика при оптимизации.
Если обращения к базе данных являются проблемой, вы можете кэшировать их на веб-сервере (или там, где находится ваше приложение), но похоже, что каждый ответ должен быть записан, когда пользователь переходит к следующему вопросу.
Если вопросы и возможные ответы одинаковы для всех, я бы определенно кэшировал их на уровне приложения - это может быть сохранено в объекте Application. В любом случае, вы можете оптимизировать вызовы базы данных, чтобы возвращать результаты как можно эффективнее - т.е. несколько наборов результатов или объединенный набор результатов из одной хранимой процедуры. Если вы не возражаете против нескольких копий для каждой сессии (или если есть вариативность), вы можете хранить их в объекте Session. Хранение на клиенте (т.е. в cookie) не совсем безопасно и бессмысленно с точки зрения экономии пропускной способности веб-сервера и клиента.
По мне, так это очень похоже на преждевременную оптимизацию.
Это классическая проблема, связанная с поддержанием состояния между страницами в системе на основе браузера. Я также предполагаю, что мы хотим, чтобы эти данные сохранялись, даже если пользователь выйдет из системы и вернется позже. Вот варианты:
Мне кажется, что первые два варианта, вероятно, не то, что вы ищете, поэтому давайте рассмотрим последний вариант.
Вы можете просто сохранить ответы в куки. Существует небольшая вероятность того, что это может быть потеряно, и что пользователь может войти в систему с другой машины, но это может быть приемлемым риском. С новейшими браузерами, поддерживающими HTML5 (включая IE8 afaik), вы получаете преимущество localStorage, которое не так легко удалить, как файл cookie. Вы можете вернуться к файлам cookie, если они недоступны.
При необходимости файлы cookie могут быть зашифрованы.
Я хотел бы предложить вам новую функцию HTML5, которая называется Dom Storage, но поскольку только новые браузеры поддерживают ее, может возникнуть проблема с использованием это на данный момент.
С помощью DOM Storage вы можете хранить данные в браузере пользователя. Поскольку он может хранить до 5 МБ на домен в Mozilla Firefox [3], Google Chrome и Opera, 10 МБ на область хранения в Internet Explorer, вы можете хранить ответы и идентификаторы вопросов в хранилище DOM.
Даже с помощью DOM Storage, не говоря уже о попадании в базу данных, вы также можете уменьшить количество обращений к серверу.
Поскольку все мы знаем, что работа с куки-файлами иногда бывает затруднительной, и они могут хранить 4 КБ, теперь самый простой способ - хранить информацию о ключах в хранилище DOM.
Вы можете хранить информацию о ключах как для сеансов, так и локально. Когда сеанс завершается, информация на основе сеанса будет удалена из браузера, но если вы сохраните локальные значения, даже если пользователь закроет вкладку, пара "ключ-значение" останется на некоторое время.
Пример кода:
<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>
Вы можете узнать больше о хранилище DOM по ссылкам ниже:
Ваш сценарий - идеальный кандидат для Predictive Fetch Pattern. Я бы предложил вам кэшировать все ваши вопросы. Когда пользователь входит в систему, используйте паттерн для получения первых 5 ответов (если он дал какие-либо ответы) и на основе его навигации (где находится его текущий вопрос) получите информацию из объекта Response или из БД.
HTH
Основываясь на моем личном опыте (обработка тысяч коротких страниц опроса в секунду), я подозреваю, что ваши опасения необоснованны. Помимо прочего, СУБД будет кэшировать такие небольшие объемы данных намного эффективнее, чем вы.
Я тестировал это, загружая вопросы и ответы в коллекцию Application-scope при запуске, а затем обслуживая их из памяти - часто это вообще не имело никакого значения.
Ваша альтернатива - отправить все сразу в браузер и написать его как приложение javascript, сохраняя данные в (зашифрованных) файлах cookie и обращаясь к базе данных только после того, как все это будет выполнено. Это утомительно, но несложно.