将数据存储到会话中并在“主要”操作时存储到数据库

时间:2014-02-26 12:21:53

标签: php mysql database performance session

我知道有数百个问题,但我要问的是略有不同。

当用户登录时,我想从数据库中的每个表中获取所有数据并将其存储在会话变量中(显然不是敏感数据,如加密密码/盐等基本上没有用的数据或没有对黑客的价值!!),当用户使用网站时,将使用存储在会话中的相关数据,而不是每次访问数据库。此外,当数据被更改或添加时,它将被写入或添加到会话文件中,并且在执行诸如“保存”或“登出”之类的主要操作时,新的/已更改的数据将被写入数据库。

我希望这样做的原因仅仅是为了提高效率,我希望我的应用程序不仅速度快,而且资源消耗更少。我不是专家,这可以解释为什么我的想法没有区别或者资源密集程度更高。

如果我的解决方案有替代方案,请告诉我,或者如果我的解决方案有待改进,我将很高兴听到。

谢谢。 我的应用程序是使用PHP和mysql。

6 个答案:

答案 0 :(得分:4)

如果其中任何一项不适用于您的应用,请忽略。一般来说,我反对使用会话作为缓存(特别是如果会话中的任何内容将被写回数据库)。这就是原因。

  • 编辑会话需要用户提出请求。在请求 - 响应周期之外编辑php会话非常困难。因此,如果用户Alice进行了影响Bob的更改,则无法弄脏Bob的缓存
  • 您不能假设用户会退出。他们可能只是离开,因此如果会话超时,您必须处理保存信息。同样,在请求 - 响应周期之外这很困难,并且在用户回来之前你不能完全保留会话文件(默认情况下php会gc)
  • 如果用户需要身份验证,则会在会话中存储私人信息。有些用户可能对此不满意。更重要的是,黑客可以利用该私人信息对最终用户进行社会工程攻击。
  • Mallory(黑客)可能无法使用您在会话中输入的信息,但可以中毒它(即缓存中毒),从而在您编写时会导致各种问题您的缓存到您的永久存储。会话比redis或memcache更容易中毒。

TL; DR使用会话缓存时需要考虑很多事项。我的建议是redis / memcache。

答案 1 :(得分:4)

您也可以在HTML5中使用,查看The GuideTHE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS

HTML5中的本地存储实际上使用您的浏览器数据库作为Cookie,但它会将数据永久存储到您的浏览器

  1. 除非有人通过强制从浏览器中删除数据来查找数据文件
  2. 或者如果有人完全删除/卸载浏览器,
  3. 或者如果有人在浏览器的私人/隐身模式下使用该应用程序,
  4. 你需要做什么

    1. 复制所需表格和所需列的架构,并定期更新数据
    2. 您不必担心用户的状态,每次用户回复您的应用程序时,您只需要将localStorage到mysql Server(以及从mysql服务器到localStorage)的完整数据更新到应用程序并保持不变定期更新数据
    3. 现在这更像是localStorage,但我认为这是我可以使用的最佳解决方案之一。

答案 2 :(得分:2)

如果可用的话,redis是一个很好的解决方案(有时开发人员因某些原因无法安装外部模块)我会做的是使用Session方法,但使用编码/加密和序列化数据。或者,我更喜欢使用HTML5 data properties,例如:

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

BTW适用于所有浏览器even with IE6,但有一些调整,特别是如果您的应用程序使用jquery和ajax。这真的很少。

答案 3 :(得分:0)

您需要使用Memcache进行此类工作。要解决在任何地方保留更新数据的问题,您可以创建用于获取数据的功能,例如,当用户登录时,对用户进行身份验证,然后将所有用户数据插入到具有唯一键的内存缓存中,例如: -

  

用户用户名的USER_ID_USERNAME

     

USER_ID_NAME代表用户名   等...

现在创建更多函数,以便在需要时获取所有这些数据。对于前

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提到用户可能永远不会注销。

答案 4 :(得分:0)

我还使用OP描述的内容来避免调用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!
}

注意: php.ini中的session.gc_maxlifetime

此值表示保护$ _SESSION多长时间不被垃圾收集器(存储$ _SESSION数据的磁盘上存在的文件)擦除

如果将此设置得非常低,用户可能会因空闲时间超过此时间而意外开始注销,因为垃圾收集器会过快删除其会话文件

如果您将此设置得非常高,您可能会在很久以前离开您网站的许多未使用的$ _SESSION文件。

我还必须补充一点,gc_maxlifetimesession.gc_probability一起使用,一般来说,您需要较低的流量网站概率和较低的流量概率,因为每个网页浏览都有{{1}垃圾收集器将被激活。

这里有更详细的解释http://www.appnovation.com/blog/session-garbage-collection-php

答案 5 :(得分:-1)

我知道这听起来很愚蠢但...... 如果您的数据不敏感,那么使其更快可访问的最佳方法是将其存储在表单本身内的隐藏变量中。您可以在数组中保存逗号分隔或值。

相关问题