Хранение данных в сеансе и хранение в базе данных по "основным" действиям

Я знаю, что есть сотни этих вопросов, но то, что я спрашиваю, несколько отличается.

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

Причина, по которой я хочу это сделать, - это просто для эффективности, я хочу, чтобы мое приложение не только быстро, но и ресурсоемкое. Я не являюсь экспертом в том, что может объяснить, почему моя идея не делает различий или более ресурсоемкой.

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

Спасибо. Мое приложение использует PHP и mysql.

Ответ 1

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

  • Для редактирования сеанса требуется запрос от пользователя. Редактирование php-сессии вне цикла запроса-ответа очень сложно. Поэтому, если пользователь Алиса вносит изменения, которые влияют на Боба, у вас нет возможности заразить Боб-кеш
  • Вы не можете предположить, что пользователи выйдут из системы. Они могут просто уйти, поэтому вам нужно иметь дело с информацией о сохранении, если сеанс не работает. Опять же, это трудно за пределами цикла запроса-ответа, и вы не можете точно оставить файлы сеанса, лежащие навсегда, пока пользователь не вернется (по умолчанию php будет gc)
  • Если пользователь требует аутентификации, вы храните личную информацию в сеансе. Некоторые пользователи могут быть недовольны этим. Что еще более важно, хакер мог внедрить эту личную информацию для проведения социальной инженерной атаки против конечного пользователя.
  • Мэллори (хакер), возможно, не сможет использовать информацию, которую вы помещаете в сеанс, но она может отравить ее (т.е. отравление кэшем), тем самым вызывая всевозможные проблемы при записи кеша в постоянное хранилище. Сессии легче отравить, затем что-то вроде redis или memcache.

TL; DR Множество соображений при использовании кеша сеанса. Моя рекомендация redis/memcache.

Ответ 2

Вы также можете перейти в HTML5, проверьте Руководство и ПРОШЛОЕ, НАСТОЯЩЕЕ И БУДУЩЕЕ МЕСТНОГО ХРАНЕНИЯ ДЛЯ ВЕБ-ПРИЛОЖЕНИЙ

Локальное хранилище в HTML5 фактически использует ваши браузеры , которая работает как файлы cookie, но сохраняет данные навсегда в вашем браузере.

  • если кто-то силой не удалит данные из браузера, находящие файлы данных
  • Или, если кто-то полностью удалит/удалит браузер,
  • или если кто-то использует приложение в режиме частного/инкогнито браузера,

Что вам нужно сделать

  • Скопируйте схему для требуемых таблиц и требуемых столбцов и обновите данные с регулярным интервалом
  • Вам не нужно беспокоиться о состоянии пользователя, вам нужно только обновить полные данные с сервера localStorage to mysql (и с сервера mysql до localStorage, если требуется), каждый раз, когда пользователь обращается к вашему приложению и продолжает обновлять данные с регулярным интервалом

Теперь это больше localStorage, но я думаю, что это одно из лучших решений для меня.

Ответ 3

redis - это хорошее решение, если оно доступно для вас (иногда разработчики не могут устанавливать внешние модули по какой-то причине), что бы я делал, это либо идти с вашим подходом к сеансу, но с закодированными/зашифрованными и сериализованными данными. Или, что я действительно предпочитаю использовать свойства данных HTML5, такие как:

<someElement id="someId" data-x="HiX" data-y="Hi-Y" />

который BTW отлично работает со всеми браузерами даже с IE6, но с некоторыми настройками, особенно если ваше приложение использует jquery и ajax. это действительно было бы немного.

Ответ 4

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

USER_ID_USERNAME для пользователя пользователя

USER_ID_NAME для имени пользователя и т.д...

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

function getName($user_id){
    if(Memcache::get($user_id."_name"){
        return Memcache::get($user_id."_name");
    } else {
        //Call another function which will fetch the data from the DB and store it in the cache
    }
}

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

Ответ 5

Я также использую то, что описал ОП, чтобы избежать вызовов на db. Например, когда пользователь входит в систему, у меня есть "приветственный совет" на панели управления, например

Welcome, <USERS NAME HERE>

Если я сохранил только его user_id на $_SESSION, то в каждом просмотре страницы мне нужно было бы получить его информацию из базы данных только для того, чтобы было доступно его имя, например SELECT user_name FROM users WHERE user_id = $_SESSION['user']['user_id'] Чтобы избежать этого, я сохраняю часть его информации в $_SESSION.

Будьте осторожны! Когда происходит изменение данных, вы должны изменить данные в db , и если успешно также изменить $_SESSION.

В моем примере, когда пользователь редактирует свое имя (которое я также храню в $_SESSION, поэтому я могу использовать его для приветствия), я делаю что-то вроде:

If (UpdateCurrentUserData($new_data)) // this is the function that modifies the db
{
    $_SESSION['user']['user_name']=$new_data['user_name']; // update session also!
}

Внимание: session.gc_maxlifetime в php.ini

В этом значении указано, сколько времени защита $_SESSION от стирания сборщика мусора (файл, который существует на вашем диске, в котором хранятся данные $_SESSION)

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

если вы установите это очень высокое значение, вы можете столкнуться с большим количеством неиспользуемых файлов $_SESSION пользователей, которые давно покинули ваш сайт.

Также я должен добавить, что gc_maxlifetime работает вместе с session.gc_probability, где в целом вам нужна меньшая вероятность для сайтов с высоким трафиком и большая вероятность для более низкого трафика, поскольку для каждого просмотра страницы есть session.gc_probability, что сборщик мусора будет активирован.

Приятное более подробное объяснение здесь http://www.appnovation.com/blog/session-garbage-collection-php

Ответ 6

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