Каков был бы лучший способ сохранить вопросы и ответы для обзора, где я должен сохранить трафик в базе данных к минимуму?

Фон
Я пишу обзор, который идет к широкой аудитории. Это содержит 15 вопросов и существует пять возможных ответов на каждый вопрос наряду с потенциальными комментариями.

Пользователь может циклически повториться через все 15 вопросов, ответив на них в любом порядке и разрешен оставить обзор в любой точке и возвратиться для ответа на остающиеся вопросы.

После того как ответ был предпринят по всем 15 вопросам, кнопка отправки появляется, который позволяет им отправлять вопросы как окончательные ответы. До того этапа все ответы требуются, чтобы быть восстановимыми каждый раз, когда пользовательские нагрузки страница обзора.

Требование - то, что пользователь только видит один вопрос на странице, и кнопки 'Previous' и 'Next' позволяют пользователю просматривать вопросы путем прокрутки.

Требование
Я мог запросить вопрос каждый раз, когда пользователь нажимает кнопку, и сохраните текущий ответ и так далее, но это было бы большим количеством хитов к базе данных, которая уже в большой степени используется. У меня нет времени для обеспечения нового сервера и т.д., таким образом, я должен суметь обойтись тем, что я имею. Есть ли какой-либо способ, которым я могу кэшировать вопросы на пользовательской машине и/или ответах? Очевидно, мне нужны данные ответа, чтобы быть безопасным и только известному пользователю, таким образом, я чувствую себя немного застрявшим что касается лучшего способа сделать это. Какие-либо указатели?

Я готов предложить щедрость 100 точек по этому вопросу, если это означает, что я получаю некоторое обсуждение хорошего качества и движение обратной связи.

7
задан Adam Robinson 12 April 2010 в 19:31
поделиться

9 ответов

У вас есть три требования, которые необходимо сбалансировать:

  • пользователи должны иметь возможность вернуться к своему опросу в любое время
  • ответы, введенные пользователями, должны быть сохранены с минимальной вероятностью потери данных
  • необходимо минимизировать попадания в базу данных

Любое решение, которое включает кеширование ответов в нестабильном месте (файлы cookie, сеанс и т. д.), увеличит риск данных потеря. Окончательное решение зависит от того, насколько важны три требования. Если проблема с базой данных находится наверху, вам придется либо рискнуть потерей данных, либо потратить много дополнительного времени на кодирование решения с использованием какой-либо схемы временного хранения (например, идея плоского файла Кевина).

Несколько человек предположили, что вы можете проводить оптимизацию раньше времени. Я предлагаю вам сначала обдумать эту идею - возможно, все это спорный вопрос.

Однако, если предположить, что ваша ситуация с БД представляет собой реальную проблему, я думаю, что вашим лучшим балансом требований будет система, которая немедленно сохраняет ответ в БД (для предотвращения потери данных), но осторожно управляет, когда вам действительно нужно попасть в БД. .

  1. Когда приложение запускается (или когда первый пользователь запрашивает опрос), загружает опрос и его вопросы в кэш приложения. Если на какой-либо из вопросов есть список возможных ответов, загрузите и его. Чтобы загрузить данные опроса, вам нужно будет только один раз нажать на базу данных за время жизни приложения (или длительность вашего кеша).
  2. Когда пользователь начинает свой опрос, выполните один запрос, чтобы загрузить любые существующие ответы (в случае, если они возвращаются) в объект в сеансе - это может быть так же просто, как строка . (Если вы можете каким-то образом идентифицировать нового пользователя, не нажимая db, вы можете пропустить этот шаг для новых пользователей.)
  3. Используйте объект ответа сеанса вместе с объектом вопроса опроса в кеше приложения, чтобы заполнить каждую страницу, не нажимая снова БД.
  4. Когда пользователь отправляет ответ, сравните его с объектом ответа сеанса, чтобы увидеть, изменился ли он (он может просто щелкнуть «далее» на странице с ранее введенным ответом). Если ответ новый или был изменен, сохраните его в базе данных и в объекте ответа сеанса.
  5. Когда пользователь покидает опрос, ничего делать не нужно - все уже сохранено.

В этой схеме вы нажимаете db один раз, чтобы загрузить опрос, один раз для каждого пользователя, когда они начинают (или перезапускают) опрос, и один раз для каждого нового или измененного ответа. Вероятно, не так много, как вы надеялись, но это дает вам лучшую защиту данных.

1
ответ дан 7 December 2019 в 01:19
поделиться

Если нет причины использовать базу данных, вы всегда можете сохранить результаты в плоских файлах на самом сервере. Это не похоже на то, что данные, которые вы храните, каким-либо образом относятся к реляционным. В худшем случае вы всегда можете вставить их обратно в реляционную базу данных в качестве пакетного задания каждую ночь.

Другой вариант - кэш приложения.Однако, если ваш веб-сервер внезапно выйдет из строя, вы рискуете потерять информацию оттуда.

Вы также можете сохранить значения в файлах cookie пользователя.

2
ответ дан 7 December 2019 в 01:19
поделиться

вы имеете в виду ... печенье?

{{1 }}
0
ответ дан 7 December 2019 в 01:19
поделиться

Не уверен, какие языки и т. Д. Вы используете, но у большинства из них есть кеш приложений. Я бы сохранил там вопросы, извлек их из базы данных и сохранил, когда их нет в кеше (когда приложение перезапускается).

Что касается ответов, пользователи как-то заходят в систему? Можно ли сохранять ответы в файле 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, если вам нужно было выполнить список, а затем получить ответ для пользователя, выполнить их в той же транзакции и сохранить поездка. Обычная практика при оптимизации.

1
ответ дан 7 December 2019 в 01:19
поделиться

Если обращения к базе данных являются проблемой, вы можете кэшировать их на веб-сервере (или там, где находится ваше приложение), но похоже, что каждый ответ должен быть записан, когда пользователь переходит к следующему вопросу.

Если вопросы и возможные ответы одинаковы для всех, я бы определенно кэшировал их на уровне приложения - это может быть сохранено в объекте Application. В любом случае, вы можете оптимизировать вызовы базы данных, чтобы возвращать результаты как можно эффективнее - т.е. несколько наборов результатов или объединенный набор результатов из одной хранимой процедуры. Если вы не возражаете против нескольких копий для каждой сессии (или если есть вариативность), вы можете хранить их в объекте Session. Хранение на клиенте (т.е. в cookie) не совсем безопасно и бессмысленно с точки зрения экономии пропускной способности веб-сервера и клиента.

По мне, так это очень похоже на преждевременную оптимизацию.

1
ответ дан 7 December 2019 в 01:19
поделиться

Это классическая проблема, связанная с поддержанием состояния между страницами в системе на основе браузера. Я также предполагаю, что мы хотим, чтобы эти данные сохранялись, даже если пользователь выйдет из системы и вернется позже. Вот варианты:

  • С сервером высокой доступности мы можем хранить одну коллекцию из 15 ответов в памяти (не сеанс) для этого пользователя (вероятно, это не очень хорошая идея и нелегко сбалансировать нагрузку)
  • Мы денормализуем 15 ответов. ответы в 1 строку таблицы sql
  • Мы сохраняем данные на клиенте, используя куки или localStorage (IE8).

Мне кажется, что первые два варианта, вероятно, не то, что вы ищете, поэтому давайте рассмотрим последний вариант.

Вы можете просто сохранить ответы в куки. Существует небольшая вероятность того, что это может быть потеряно, и что пользователь может войти в систему с другой машины, но это может быть приемлемым риском. С новейшими браузерами, поддерживающими HTML5 (включая IE8 afaik), вы получаете преимущество localStorage, которое не так легко удалить, как файл cookie. Вы можете вернуться к файлам cookie, если они недоступны.

При необходимости файлы cookie могут быть зашифрованы.

1
ответ дан 7 December 2019 в 01:19
поделиться

Я хотел бы предложить вам новую функцию 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 по ссылкам ниже:

1
ответ дан 7 December 2019 в 01:19
поделиться

Ваш сценарий - идеальный кандидат для Predictive Fetch Pattern. Я бы предложил вам кэшировать все ваши вопросы. Когда пользователь входит в систему, используйте паттерн для получения первых 5 ответов (если он дал какие-либо ответы) и на основе его навигации (где находится его текущий вопрос) получите информацию из объекта Response или из БД.

HTH

1
ответ дан 7 December 2019 в 01:19
поделиться

Основываясь на моем личном опыте (обработка тысяч коротких страниц опроса в секунду), я подозреваю, что ваши опасения необоснованны. Помимо прочего, СУБД будет кэшировать такие небольшие объемы данных намного эффективнее, чем вы.

Я тестировал это, загружая вопросы и ответы в коллекцию Application-scope при запуске, а затем обслуживая их из памяти - часто это вообще не имело никакого значения.

Ваша альтернатива - отправить все сразу в браузер и написать его как приложение javascript, сохраняя данные в (зашифрованных) файлах cookie и обращаясь к базе данных только после того, как все это будет выполнено. Это утомительно, но несложно.

2
ответ дан 7 December 2019 в 01:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: