>  기사  >  백엔드 개발  >  如何用缓存技术?

如何用缓存技术?

WBOY
WBOY원래의
2016-06-20 12:43:41968검색

请教各位高手,例如我的index.php页面主要如下:
include("IncDB.php"); 
session_start () ;
$result=mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc limit 1",$link);
$row = mysql_fetch_row($result);
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";

mysql_close($link); 
?> 

每次用户登录后,都要从数据库里读数据,再显示出来,会比较慢,有没有什么方法如缓存技术,当信息无变化时,能直接从某页面调取,而 不用每次再从数据库查询,然后再显示出来。谢谢大家。


回复讨论(解决方案)

我自己在网上看,可以用缓存技术,但我还是不明白具体怎么做?还请指教。谢谢!

是 可以用缓存
不过你的缓存策略是什么
缓存到哪里
如何知道数据发生了变化

这些你思考过吗?

我不懂啊哥,没思考过。因为上面这个页面会根据不同 的用户,内容也会变化,我琢磨缓存放在网站肯定不行吧,要不得为每一个用户建一个缓存备用,是不是应该在客户端?数据发生变化,是不是可以让后台来校验,但网页主动刷新时,就能把最新信息显示出来?

我的需求就是找一个办法,使得用户在打开这个页面时,不用每次都从数据库提数据,那样确实比较慢,因为该页面提取的数据比较多。

您能帮我看看怎么弄呢?谢谢!

不过这个页面如发生变化,有两种情况,一个是后台管理时做调整,内容会变化,这个可能几个月才能有一次,可以忽略;二是,用户通过EDIT.php页面修改userlinks里面的数据,这时候,内容就要发生变化了。
另外,我能把某个页面,如EDIT.php缓存到客户端吗?我发现每次用户打开都特别慢。
不知道我说清楚没有,大神。

你可以存SQL的查询结果,储存到缓存里面

文件缓存。

<?php include("IncDB.php"); session_start () ;$cache_file = dirname(__FILE__).'/cache.file';$expire = 60;$cache_data = json_decode(file_get_contents($cache_file), true);if(!$cache_data || time()-$cache_data['expire']>$expire){    $result=mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc limit 1",$link);    $row = mysql_fetch_row($result);    $cache_data = json_encode(array('data'=>$row,'expire'=>time()));}else{    $row = $cache_data['data'];}echo "$row[1]"; echo"<br>"; echo "$row[2]";mysql_close($link); ?> 

谢谢各位大神。很抱歉,我很水,看了半天没明白这代码的含义,能帮我解释一下么?另外,6楼的代码是不是就是5楼说的,存SQL的查询结果,储存到缓存里面?
我觉得要是能实现把查询的数据存到本地,然后每次从本地读取就能实现我说的功能了。

我自己猜,好像代码是给缓存规定了一个更新时间,时间内就缓存读取,否则就数据库。如果这样,就不对了,因为,用户会通过edit.php页面随时就某个内容修改好多次,但也可能几个月都不改一次。因此如果对缓存规定更新时间不行。是否应该在edit页面中增加更新缓存的代码,而index页面直接读取本地缓存就行?如果本地没有,就读数据库?

对了,我贴的代码有误,提取的数据是多行,没有limit 1。不好意思。

建议你使用memcache缓存(把SQL的查询结果放到服务器的内存里),如果用户在edit.php更新了数据,那么就把memcache里的缓存清掉,然后index.php去查询缓存时,if(memcache缓存不存在){使用SQL语句更新数据}。

sorry,大哥,我不会啊,怎么用memcache啊?我在网上看到有说用这个的,是在edit页面增加语句么?还是其他?我啥都不懂啊。不好意思,能告诉我是什么代码,写在哪里?原谅我的无知。

index.php:

include("IncDB.php"); session_start () ;//使用memcache对象$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211if(!$memcache->get('results')){	$result = mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc", $link);	$row = mysql_fetch_row($result);	echo "$row[1]"; 	echo"<br>"; 	echo "$row[2]";	mysql_close($link); 	$memcache->set('results', $row);}


edit.php:
//在edit.php里,用户更新了数据,则清除memcache缓存。//用户更新数据代码.....$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211$memcache->delete('results', 0); //0表示该元素立即删除

既然 也可能几个月都不改一次,那么直接生成和使用静态页就是了,何必用什么缓存?

谢谢大神们。我回去试试。谢谢!
回xuzuning,是后台改,几个月才一次,但用户改,可能频率就高了。谢谢关心。

我追问一下misakaqunianx.,我不懂啊。1、根据您给的方法我提取数据比如有10条,缓存这10条数据后,如果用户后来改了其中的一条如第5条,也能通过EDIT页面的$memcache实现精确更新该条数据么?
2、在index页面中,哪一句是说从本地缓存提取数据的?我看不明白。
3、如果用户在本地有两个用户名,不会影响吧?
不好意思,问的太弱了。

谢谢大神们!

我追问一下misakaqunianx.,我不懂啊。1、根据您给的方法我提取数据比如有10条,缓存这10条数据后,如果用户后来改了其中的一条如第5条,也能通过EDIT页面的$memcache实现精确更新该条数据么?
2、在index页面中,哪一句是说从本地缓存提取数据的?我看不明白。
3、如果用户在本地有两个用户名,不会影响吧?
不好意思,问的太弱了。


只要你的用户修改了任意数据,你就把memcache的缓存清除掉,这样就可以保证不管修改了什么,都会重新用SQL查询数据库。
$memcache->get('results')是从内存里取出缓存(memcache不是文件缓存,而是放到服务器内存里缓存)
如果要使用memcache,需要开启memcache的扩展,方法就百度去吧。

我要是上传到空间里去,就不必要我还要增加您说的代码即可吧?再开启扩展了吧,服务商自己应该开好了吧,谢谢。

我要是上传到空间里去,就不必要我还要增加您说的代码即可吧?再开启扩展了吧,服务商自己应该开好了吧,谢谢。


一般情况下,服务商都是开启了的。

谢谢,我回去试后结贴,谢谢。

好像不行啊,我增加以后,页面什么都显示不了了。我还有几个疑问请教:
1、按照我的理解,逻辑是先判断缓存有无数据,如有则从缓存提取数据;如没有,则从数据库提取数据,并ECHO,然后 $memcache->set('results', $row);但是您的代码,我理解不了这个思路,没有if else,只有if。
2、如果我的页面中需要提取好几次数据,如$result = mysql_query...,还有$result1 = mysql_query...,是不是每次提取数据时都得加这些代码?还是一个页面,只要设置一次,然后get('results'),get('results1'),get('results2')就可以了?
3、$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211
这一句,我能加到IncDB.php(这是链接数据库设置的文件)中去,统一调用么?
谢谢指点。

能教教我么?谢谢啊。

这个。。。。。。。

大神们,有空稍微理一下我吧...

好像不行啊,我增加以后,页面什么都显示不了了。我还有几个疑问请教:
1、按照我的理解,逻辑是先判断缓存有无数据,如有则从缓存提取数据;如没有,则从数据库提取数据,并ECHO,然后 $memcache->set('results', $row);但是您的代码,我理解不了这个思路,没有if else,只有if。
2、如果我的页面中需要提取好几次数据,如$result = mysql_query...,还有$result1 = mysql_query...,是不是每次提取数据时都得加这些代码?还是一个页面,只要设置一次,然后get('results'),get('results1'),get('results2')就可以了?
3、$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211
这一句,我能加到IncDB.php(这是链接数据库设置的文件)中去,统一调用么?
谢谢指点。


1、我忘了写了   else{ $row = $memcache->get('results'); }
2、每次提取数据时都需要加这些代码先判断缓存。
3、不需要放到数据库配置里,memcache是缓存扩展,放在系统配置里就可以了。

哥 啊,是在代码的最后,加上else{ $row = $memcache->get('results'); }就可以了?系统配置是什么?我的就是这个页面,如果不把那些代码($memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);)放在一个文件里调用,如IncDB.php,我每次都得再写啊。我没有专门的系统配置页面。

使用 memcache 需要安装 memcached 服务器和与 php 版本对应的 php_memcache 扩展

如果是全局使用,那么
$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);
只需写一次,当然可以写在嵌入文件中
但你并不能保证不会在函数里使用

其实你的核心问题还是我一开始就提出的:你如何知道内容发生的变化
如果你不解决这个问题,什么其他技术手段的是枉然的

哥 啊,是在代码的最后,加上else{ $row = $memcache->get('results'); }就可以了?系统配置是什么?我的就是这个页面,如果不把那些代码($memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);)放在一个文件里调用,如IncDB.php,我每次都得再写啊。我没有专门的系统配置页面。


既然没有配置文件,那就放到IncDB.php里就好了。
<?phpinclude("IncDB.php"); session_start () ;//使用memcache对象$memcache = new Memcache;$memcache->connect('memcache主机地址', 11211); //memcache默认端口号是11211if(($row = $memcache->get('results')) == false){		//缓存里没有得到results,则去数据库查询	$result = mysql_query("SELECT * FROM userlinks where id='a02' and userid=‘".$_SESSION['id']."’ order by datetime desc", $link);	$row = mysql_fetch_row($result);	mysql_close($link); 	$memcache->set('results', $row); //查询数据库之后再放入缓存}echo "$row[1]"; echo"<br>"; echo "$row[2]";?>

使用 memcache 需要安装 memcached 服务器和与 php 版本对应的 php_memcache 扩展

如果是全局使用,那么
$memcache = new Memcache;
$memcache->connect('memcache主机地址', 11211);
只需写一次,当然可以写在嵌入文件中
但你并不能保证不会在函数里使用

其实你的核心问题还是我一开始就提出的:你如何知道内容发生的变化
如果你不解决这个问题,什么其他技术手段的是枉然的


是用户在EDIT页面,修改数据后,该内容才会发生变化。也就是说,我可以写在IncDB.php文件里调用就可以了?谢谢!

谢谢两位大神。。。我试试。

memcached 的内容是保存在内存中的,因此系统重启后,缓存的内容都会消失。
所以仅在修改的时候写缓存是不够的

那有办法么?我的初衷就是想提高网页响应速度,memcached能够实现么?

另外,如果我有1万个用户,那么在服务器上就得要存1万套数据?不知是否理解正确。我觉得能存在客户端最好,但不知怎么把一条条数据存在客户端并读取。

要做缓存,肯定要考虑更新数据的情况,比如你说的用户有可能修改资料。 你在程序里,就在用户修改资料后,把相应的缓存删掉就行了。

谢谢楼上的提示。
我崩溃了,就是不行,也没有报错。我是这么写的

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";}

?> 

谢谢楼上的提示。
我崩溃了,就是不行,也没有报错。我是这么写的

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";}

?> 


在程序的各个位置打印一下可能出错的变量,排错是个麻烦的过程。

这么晚还回了?感谢。弱弱的问,咋写啊。不要问我有多水~~~

这么晚还回了?感谢。弱弱的问,咋写啊。不要问我有多水~~~


用var_dump()来打印啊。。。话说,这个memcache缓存你完全可以自己找点资料,看看别人的博客去学习的。。。

这么问永远没个头,把里面提到的几个关键的内容去学习一下,然后在学习的时候遇到不明白的地方再来问效率会更好 不然下次你还是得问这些问题。

memcache
文件缓存

我其实是研究了几天之后,还是没搞明白才发帖求助的,可能是基础太差,也可能是智商不在家,反正没搞懂。

我写成这样,是不是就能打印错误了?

include("IncDB.php"); 
session_start () ;
 $memcache = new Memcache;
$memcache->connect('localhost',11211) or die("链接失败!");
if(($row = $memcache->get('results')) == false){
 $result = mysql_query("SELECT * FROM userlinks where id='a02' and userid='".$_SESSION['id']."' order by datetime desc ", $link);
    $row = mysql_fetch_row($result);
var_dump($row)
 echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
    $memcache->set('results', $row); 
 mysql_close($link);}
else{ $row = $memcache->get('results'); 
echo "$row[1]"; 
echo"
"; 
echo "$row[2]";
var_dump($row)}

?> 

既然你是在调试程序,并多出打印点
那么你应该给出程序的运行结果吧?

xuzuning 好,我现在单位,没法把页面上传到空间,所有还不知道调试结果。另外,我那个多出打印点的代码对吗?
还有,我觉得您说的策略的确是问题,而且,我也觉得要是能把数据存到客户端是最好的。我的每个页面很简单,也很小,但内容都是从数据库里提取数据显示,而每个用户页面显示的内容,除了用户自己修改会立即有变化以外,其他一般变化不大(可能几个月才变一点)。因为每次从数据库提数慢,我就想如果能实现把每个用户的数据缓存在客户端,然后当其自己修改时再更新该缓存就可以了。不知道是否可以实现。另外,这些页面,当我在本地测试时很快,一上传空间就慢的没法用了。

再回PhpNewnew,我其实各种途径学习缓存有一个多礼拜,但确实没搞懂。我也知道老麻烦别人不好。放心,如果我还是没学会,我会及时结贴的。谢谢关心。



 你这个 用 memcache  是不行的。这个缓存技术用不了,你这个上面。

最好,缓存到服务器文件,注明一下时间。然后,用户每次改,也记录时间。时间不对上,就重新缓存。

这是概念。。

其实你现在的问题,是打开慢,这个暂时还不需要缓存的,你在数据表中,加索引,打开就很快了。

我看到这个帖子http://www.2cto.com/kf/201407/319353.html
上面好像就说了,可以在客户端存储读取数据。我不知道是否可行。

你先把概念弄清楚!本地是一个相对概念:
浏览器访问你的 php 网站,那么浏览器所在的机器就是本地
php 访问数据库服务器,那么 php 所在的机器就是本地
你给的那个连接中并没有说把数据缓存到了客户端(当然相对于数据库,php也是客户端)

如果你这的希望将页面缓存到客户的浏览器缓冲区去的话,只需要当客户再次访问时发个 304 头就可以了
当然你依然还是要知道数据是否发生了变化。于是问题又回到了原点: 你如何知道内容发生的变化
只有这个问题解决了,才有上技术手段的可能

用户在修改了内容以后就内容就发生变化了。我知道你有种对牛弹琴的感觉,但我确实low,也没办法。sorry
如果换个角度,我的原始需求就是希望不用每次访问数据库获得数据,来提高响应速度,您有什么建议?谢谢大神。

1. 先写一个memcache的简单实例,网上查下有很多,熟悉了之后,再应用到自己的代码中。

2. 提一点,memcache有一个过期时间的,设置了过期时间,就不用担心数据存到里面会越来越大了。

3. 大致思路,
a. 每次更新数据,更新之后,去memcached检查,如果存在,则更新memcached;如果不存在,则不做动作。
b. 每次访问数据,先去memcahced检查,如果存在则直接取出使用;如果不存在则从数据库获取,并存于memcached。

4. memcached有个小缺点,数据类型单一,且不会将数据写入硬盘。如果有这方面的需求,建议看看redis。redis还有主从备份。
redis用法请参照第1-3点,将memcached都改成redis。

还是没学会,我放弃了!谢谢各位大神。。。。

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.