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

时间:2022-08-08 16:59:40

I know there are hundreds of these questions but what I am asking however is slightly different.

我知道有成百上千个这样的问题,但我所问的却略有不同。

When the user logs in I would like to get all their data from each table in a database and store it in a session variable (obviously not sensative data such as encrypted password/salts etc basically data that would be useless or have no value to a hacker!!), and whilst the user uses the website the relevant data stored in the session will be used as opposed to accessing the database everytime. Moreover when the data is changed or added this will be written or added to the session file, and upon a major action such as "saving" or "loggin out" the new/changed data will be written to the database.

当用户登录时我想要所有的数据从数据库中每个表并将它存储在一个会话变量(显然不是sensative数据加密的密码/盐等基本数据,将是无用的或没有价值的黑客! !),并在用户使用该网站的相关数据存储在会话中使用,而不是每次访问数据库。此外,当数据被修改或添加时,它将被写入或添加到会话文件中,并且在执行“保存”或“loggin out”等重大操作时,新的/更改的数据将被写入数据库。

The reason I wish to do this is simply for efficieny, I want my application to not only be fast but less resource consuming. I am no expert on either which may explain why my idea makes no differnece or is more resource intensive.

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

If there is an alternative to my solution please let me know or if there is something to improve on my solution I will be glad to hear it.

如果我的解决方案有其他选择,请告诉我,或者如果我的解决方案有什么需要改进的地方,我会很高兴听到。

Thank you. My application is using PHP and mysql.

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

6 个解决方案

#1


3  

If any of these don't apply to your app, then please ignore. In general, I'm against using sessions as caches (especially if anything in the session is going to be written back to the DB). Here's why.

如果这些都不适用于你的应用程序,请忽略。通常,我反对将会话用作缓存(特别是会话中的任何内容将被写入到DB)。这是为什么。

  • Editing the session requires a request from the user. Editing a php session outside of the request-response cycle is very difficult. So if a user Alice makes a change which affects Bob, you have no way to dirty Bob's cache
  • 编辑会话需要用户的请求。在请求-响应周期之外编辑php会话非常困难。因此,如果用户Alice做了一个影响Bob的更改,您就无法脏了Bob的缓存
  • You can't assume users will log out. They may just leave so you have to deal with saving info if the session times out. Again, this is difficult outside of the request-response cycle and you can't exactly leave session files lying around forever until the user comes back (php will gc them by default)
  • 你不能假设用户会退出。他们可能只是离开,所以你必须处理保存信息如果会议超时。同样,这在请求-响应周期之外是很困难的,而且在用户返回之前,您不能将会话文件一直放在那里(php将在默认情况下对它们进行gc)
  • If the user requires authentication, you're storing private information in the session. Some users may not be happy about that. More importantly, a hacker could imploy that private information to conduct a social engineering attack against the end-user.
  • 如果用户需要身份验证,那么您正在会话中存储私有信息。一些用户可能对此不满意。更重要的是,黑客可以利用这些私人信息对最终用户进行社会工程攻击。
  • Mallory (a hacker) might not be able to use the information you put in the session, but she can poison it (ie. cache poisoning), thereby causing all sorts of problems when you write your cache to your permanent storage. Sessions are easier to poison then something like redis or memcache.
  • Mallory(一个黑客)可能不能使用你在会话中输入的信息,但是她可以毒害它。缓存中毒),因此,当您将缓存写到您的永久存储时,会导致各种各样的问题。会话比redis或memcache更容易被破坏。

TL;DR Lots of considerations when using a session cache. My recommendation is redis/memcache.

在使用会话缓存时,需要考虑很多问题。我的建议是复述/ memcache。

#2


4  

You can also go for in HTML5, check The Guide and THE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS

您还可以使用HTML5中的本地存储,查看指南和WEB应用程序本地存储的过去、现在和未来

Local Storage in HTML5 actually uses your browsers database that works as cookies but it stores data permanently to your browser

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

  1. unless someone by force remove the data from the browser finding the data files
  2. 除非有人强制从浏览器中删除查找数据文件的数据
  3. Or if someone remove/uninstall browser completely,
  4. 如果某人完全删除/卸载浏览器,
  5. or if someone uses the application in private/incognito mode of the browser,
  6. 或者如果有人在浏览器的私隐模式下使用应用程序,

What you need to do

你需要做什么

  1. Copy the schema for required tables and for required columns and update data at a regular interval
  2. 复制所需表和所需列的模式,并定期更新数据
  3. you dont have to worry about user's state, you only have to update the complete data from the localStorage to mysql Server (and from the mysql server to localStorage if required) every time user backs to your application and keep updating the data at regular interval
  4. 您不必担心用户的状态,只需在每次用户返回应用程序并定期更新数据时,从localStorage更新到mysql服务器(如果需要,从mysql服务器更新到localStorage)

Now this is turning out to be more of localStorage but I think this is one of the best solution available for me.

现在,这更多的是localStorage,但我认为这是我所能得到的最好的解决方案之一。

#3


2  

redis is a good solution if it is available for you (sometimes developers can't install external modules for some reason) what I would do is either go with your Session approach but with encoded/encrypted and serialized data. Or, which I really prefer is to use HTML5 data properties such as:

如果redis对您可用(有时开发人员由于某些原因无法安装外部模块),那么它是一个很好的解决方案。或者,我更喜欢使用HTML5数据属性,比如:

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

which BTW works fine with all browsers even with IE6 but with some tweaks, specially if your application uses jquery and ajax. this would really be handful.

这对所有浏览器都适用,即使是IE6,也有一些调整,特别是如果应用程序使用jquery和ajax。这真的很难。

#4


0  

You need to use Memcache for this kind of work. To solve the problem of keeping the updated data everywhere you can create functions for fetching the data, for example when the user logs in you, authenticate the user and after that insert all the user data into the memcache with unique keys like :-

这种工作需要使用Memcache。为了解决将更新的数据保存在任何地方的问题,您可以创建获取数据的函数,例如,当用户登录时,对用户进行身份验证,然后将所有用户数据插入到memcache中,并使用惟一的键,比如:-

USER_ID_USERNAME for user's username

USER_ID_USERNAME对用户的用户名

USER_ID_NAME for user's name etc...

USER_ID_NAME用户名等…

Now create some more functions to fetch all this data whenever you need it. For 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
    }
}

You will need to create functions to fetch every kind of data related to the user. And as you said you want to update this data on some major event. You can try updating the data using CRON or something like that, because as tazer84 mentioned users may never log out.

您将需要创建函数来获取与用户相关的各种数据。正如你所说,你想要更新一些重大事件的数据。您可以尝试使用CRON或类似的东西来更新数据,因为tazer84提到用户可能永远不会注销。

#5


0  

I also use what the OP described to avoid calls to db. For example, when a user logs-in, i have a "welcome-tip" on their control panel like

我还使用了OP描述的避免调用db的操作。例如,当用户登录时,我在他们的控制面板上有一个“欢迎提示”。

Welcome, <USERS NAME HERE>

欢迎, <用户名>

If i stored only his user_id on $_SESSION then in every pageview i would have to retrieve his information from the database just to have his name available, like SELECT user_name FROM users WHERE user_id = $_SESSION['user']['user_id'] So to avoid this, i store some of his information in $_SESSION.

如果我在$_SESSION中只存储了他的user_id,那么在每个pageview中,我都必须从数据库中检索他的信息,才能获得他的名字,比如从user_id = $_SESSION['user']['user_id']的用户中选择user_name,为了避免这种情况,我将他的一些信息存储在$_SESSION中。

Be careful! When there is a change on data, you must modify the data in db and if successfull also modify the $_SESSION.

小心!当数据发生更改时,必须修改db中的数据,如果successfull也修改$_SESSION。

In my example, when a user edits his name (which i also store in $_SESSION so i can use it to welcome-tip), i do something like:

在我的示例中,当用户编辑他的名字(我也将其存储在$_SESSION中,以便使用它来欢迎提示)时,我做如下操作:

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

Attention to: session.gc_maxlifetime in your php.ini

注意:会话。gc_maxlifetime在php . ini中

This value says how much time the $_SESSION is protected from being erased by the garbage collector (the file that exists on your disk in which the $_SESSION data are stored)

这个值表示$_SESSION被垃圾收集器删除的时间(存在于存储$_SESSION数据的磁盘上的文件)

If you set this very low, users may start getting logged-out unexpectedly if they are idle more than this amount of time because garbage collector will delete their session file too quickly

如果您将其设置得非常低,那么如果用户空闲的时间超过这个时间,那么他们可能会意外地收到loggeout,因为垃圾收集器将很快删除他们的会话文件

if you set this very high, you may end up with lots of unused $_SESSION files of users that have left your website a long time ago.

如果您将其设置得非常高,您可能会得到许多用户的未使用的$_SESSION文件,这些文件在很久以前就已经离开了您的网站。

also i must add that gc_maxlifetime works together with session.gc_probability where in general you need lower probability for high-traffic websites and bigger probability for lower traffic since for each pageview there is a session.gc_probability that garbage collector will be activated.

我还必须添加gc_maxlifetime与session一起工作。一般来说,高流量网站需要更低的概率,低流量需要更大的概率,因为每个页面视图都有一个会话。可能会激活垃圾收集器。

A nice more detailed explanation here http://www.appnovation.com/blog/session-garbage-collection-php

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

#6


-1  

I know this sounds stupid but .... If ur data is not sensitive the best way to make it accessible faster is to store it in hidden variables inside the forms itself. You can save comma separated or values in an array.

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

#1


3  

If any of these don't apply to your app, then please ignore. In general, I'm against using sessions as caches (especially if anything in the session is going to be written back to the DB). Here's why.

如果这些都不适用于你的应用程序,请忽略。通常,我反对将会话用作缓存(特别是会话中的任何内容将被写入到DB)。这是为什么。

  • Editing the session requires a request from the user. Editing a php session outside of the request-response cycle is very difficult. So if a user Alice makes a change which affects Bob, you have no way to dirty Bob's cache
  • 编辑会话需要用户的请求。在请求-响应周期之外编辑php会话非常困难。因此,如果用户Alice做了一个影响Bob的更改,您就无法脏了Bob的缓存
  • You can't assume users will log out. They may just leave so you have to deal with saving info if the session times out. Again, this is difficult outside of the request-response cycle and you can't exactly leave session files lying around forever until the user comes back (php will gc them by default)
  • 你不能假设用户会退出。他们可能只是离开,所以你必须处理保存信息如果会议超时。同样,这在请求-响应周期之外是很困难的,而且在用户返回之前,您不能将会话文件一直放在那里(php将在默认情况下对它们进行gc)
  • If the user requires authentication, you're storing private information in the session. Some users may not be happy about that. More importantly, a hacker could imploy that private information to conduct a social engineering attack against the end-user.
  • 如果用户需要身份验证,那么您正在会话中存储私有信息。一些用户可能对此不满意。更重要的是,黑客可以利用这些私人信息对最终用户进行社会工程攻击。
  • Mallory (a hacker) might not be able to use the information you put in the session, but she can poison it (ie. cache poisoning), thereby causing all sorts of problems when you write your cache to your permanent storage. Sessions are easier to poison then something like redis or memcache.
  • Mallory(一个黑客)可能不能使用你在会话中输入的信息,但是她可以毒害它。缓存中毒),因此,当您将缓存写到您的永久存储时,会导致各种各样的问题。会话比redis或memcache更容易被破坏。

TL;DR Lots of considerations when using a session cache. My recommendation is redis/memcache.

在使用会话缓存时,需要考虑很多问题。我的建议是复述/ memcache。

#2


4  

You can also go for in HTML5, check The Guide and THE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS

您还可以使用HTML5中的本地存储,查看指南和WEB应用程序本地存储的过去、现在和未来

Local Storage in HTML5 actually uses your browsers database that works as cookies but it stores data permanently to your browser

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

  1. unless someone by force remove the data from the browser finding the data files
  2. 除非有人强制从浏览器中删除查找数据文件的数据
  3. Or if someone remove/uninstall browser completely,
  4. 如果某人完全删除/卸载浏览器,
  5. or if someone uses the application in private/incognito mode of the browser,
  6. 或者如果有人在浏览器的私隐模式下使用应用程序,

What you need to do

你需要做什么

  1. Copy the schema for required tables and for required columns and update data at a regular interval
  2. 复制所需表和所需列的模式,并定期更新数据
  3. you dont have to worry about user's state, you only have to update the complete data from the localStorage to mysql Server (and from the mysql server to localStorage if required) every time user backs to your application and keep updating the data at regular interval
  4. 您不必担心用户的状态,只需在每次用户返回应用程序并定期更新数据时,从localStorage更新到mysql服务器(如果需要,从mysql服务器更新到localStorage)

Now this is turning out to be more of localStorage but I think this is one of the best solution available for me.

现在,这更多的是localStorage,但我认为这是我所能得到的最好的解决方案之一。

#3


2  

redis is a good solution if it is available for you (sometimes developers can't install external modules for some reason) what I would do is either go with your Session approach but with encoded/encrypted and serialized data. Or, which I really prefer is to use HTML5 data properties such as:

如果redis对您可用(有时开发人员由于某些原因无法安装外部模块),那么它是一个很好的解决方案。或者,我更喜欢使用HTML5数据属性,比如:

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

which BTW works fine with all browsers even with IE6 but with some tweaks, specially if your application uses jquery and ajax. this would really be handful.

这对所有浏览器都适用,即使是IE6,也有一些调整,特别是如果应用程序使用jquery和ajax。这真的很难。

#4


0  

You need to use Memcache for this kind of work. To solve the problem of keeping the updated data everywhere you can create functions for fetching the data, for example when the user logs in you, authenticate the user and after that insert all the user data into the memcache with unique keys like :-

这种工作需要使用Memcache。为了解决将更新的数据保存在任何地方的问题,您可以创建获取数据的函数,例如,当用户登录时,对用户进行身份验证,然后将所有用户数据插入到memcache中,并使用惟一的键,比如:-

USER_ID_USERNAME for user's username

USER_ID_USERNAME对用户的用户名

USER_ID_NAME for user's name etc...

USER_ID_NAME用户名等…

Now create some more functions to fetch all this data whenever you need it. For 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
    }
}

You will need to create functions to fetch every kind of data related to the user. And as you said you want to update this data on some major event. You can try updating the data using CRON or something like that, because as tazer84 mentioned users may never log out.

您将需要创建函数来获取与用户相关的各种数据。正如你所说,你想要更新一些重大事件的数据。您可以尝试使用CRON或类似的东西来更新数据,因为tazer84提到用户可能永远不会注销。

#5


0  

I also use what the OP described to avoid calls to db. For example, when a user logs-in, i have a "welcome-tip" on their control panel like

我还使用了OP描述的避免调用db的操作。例如,当用户登录时,我在他们的控制面板上有一个“欢迎提示”。

Welcome, <USERS NAME HERE>

欢迎, <用户名>

If i stored only his user_id on $_SESSION then in every pageview i would have to retrieve his information from the database just to have his name available, like SELECT user_name FROM users WHERE user_id = $_SESSION['user']['user_id'] So to avoid this, i store some of his information in $_SESSION.

如果我在$_SESSION中只存储了他的user_id,那么在每个pageview中,我都必须从数据库中检索他的信息,才能获得他的名字,比如从user_id = $_SESSION['user']['user_id']的用户中选择user_name,为了避免这种情况,我将他的一些信息存储在$_SESSION中。

Be careful! When there is a change on data, you must modify the data in db and if successfull also modify the $_SESSION.

小心!当数据发生更改时,必须修改db中的数据,如果successfull也修改$_SESSION。

In my example, when a user edits his name (which i also store in $_SESSION so i can use it to welcome-tip), i do something like:

在我的示例中,当用户编辑他的名字(我也将其存储在$_SESSION中,以便使用它来欢迎提示)时,我做如下操作:

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

Attention to: session.gc_maxlifetime in your php.ini

注意:会话。gc_maxlifetime在php . ini中

This value says how much time the $_SESSION is protected from being erased by the garbage collector (the file that exists on your disk in which the $_SESSION data are stored)

这个值表示$_SESSION被垃圾收集器删除的时间(存在于存储$_SESSION数据的磁盘上的文件)

If you set this very low, users may start getting logged-out unexpectedly if they are idle more than this amount of time because garbage collector will delete their session file too quickly

如果您将其设置得非常低,那么如果用户空闲的时间超过这个时间,那么他们可能会意外地收到loggeout,因为垃圾收集器将很快删除他们的会话文件

if you set this very high, you may end up with lots of unused $_SESSION files of users that have left your website a long time ago.

如果您将其设置得非常高,您可能会得到许多用户的未使用的$_SESSION文件,这些文件在很久以前就已经离开了您的网站。

also i must add that gc_maxlifetime works together with session.gc_probability where in general you need lower probability for high-traffic websites and bigger probability for lower traffic since for each pageview there is a session.gc_probability that garbage collector will be activated.

我还必须添加gc_maxlifetime与session一起工作。一般来说,高流量网站需要更低的概率,低流量需要更大的概率,因为每个页面视图都有一个会话。可能会激活垃圾收集器。

A nice more detailed explanation here http://www.appnovation.com/blog/session-garbage-collection-php

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

#6


-1  

I know this sounds stupid but .... If ur data is not sensitive the best way to make it accessible faster is to store it in hidden variables inside the forms itself. You can save comma separated or values in an array.

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