+ -
当前位置:首页 → 问答吧 → [讨论]:万物皆可缓存,浅谈缓存之道

[讨论]:万物皆可缓存,浅谈缓存之道

时间:2009-05-26

来源:互联网

[原理]:我们开发网站时经常不可避免的要对数据库做一定的操作,而在我看来很多操作都是重复性的,例如我们做一个产品的列表,可能同时有数十个数百个客户同时在浏览这类产品列表,也就是说不同的进程同时要处理同一件事,客户-》请求数据库-》数据库查询出结果-》返回给客户看最终结果,可能有不少人会有这么个想法,我直接生成html静态页面不就可以处理了吗?是的,这点确时可以解决不少问题,但我们想一下,如果在一些特殊情况比如特殊搜索的时候生成html的可能性就降得比较低,例如,用户搜索关键字"ThinkPHP",可能同也有别的客户在搜索这类关键字,也可能会有10个或100个客户在10分钟内搜索这个关键字,难不成我们得一次一次的搜索数据库得出结果再返回给数据库?所以我认为缓存机制的合理利用对一个网站的合理利用效率是很有帮助的。

[构想]:我们可以将用户查询的结果或者经常用到的一些数据或者是一些中间变量缓存至CACHE,在TP中建立了比较完善的cache机制,有文件和其它的第三方控制的缓存机制,这样便于我们灵活的掌握以结省效率。
          这里只提出两类构想,第一类我这里称为:db->arrray 即数据库缓存至数组,先放出代码,各位大侠指点一下。
  1. function dbtoary($table,$condition='',$encache=1,$cache_life=5){
  2. if($table==''){return false;}
  3. $cache_life=($cache_life<0)?-1:$cache_life*60;//以分钟为单位
  4. $table=ucfirst($table);
  5. $my_cond=(is_array($condition))?array_string($condition,' and '):$condition;//array_string是将数据的键和值变成字符串
  6. $is_cache=($encache==0)?true:false;
  7. if(1==$encache)
  8. {$temp_data = S('temp_'.$table.$my_cond);
  9.   if($temp_data['condition']==$my_cond and ($temp_data['cache_life']==-1 or $temp_data['cache_life']>time()))
  10.   {$is_cache=true;return $temp_data['data'];}
  11. }
  12. $Dao = D("$table");
  13. $list = $Dao->where($my_cond)->select();
  14. if(false===$list){return false;}
  15. if($encache>1 or false==$is_cache)
  16. {$data['condition']=$my_cond;
  17.   $data['cache_life']=($cache_life<=0)?-1:time()+$cache_life;//以分钟为单位;
  18.   $data['data']=$list;
  19.   S('temp_'.$table.$my_cond,$data,$cache_life);
  20. }
  21. return $list;
  22. }
复制代码
调用方法:
$data = dbtoary("User",array('sex'=>1));
来进行读取数据,函数默认为5分钟,可以根据具体情况进行调整缓存时间,如置为-1则永久缓存。
函数存储了用户的条件请求,数据表,以数据表,条件请求为结果,进行缓存。

函数存储了用户的条件,有效期时间(其实这项也可以省略,但我本人的项目因为缓存比较多,所以存储这项以免一些不毕要的载入cache错误,此项可根据需要进行修改)过期则重新载入。

此种方法的缺点:如果客户找不到数据则此项会做的工作比直接读取数据来得更麻烦,所以针对须要的做是最好的。

[注]:此方法适用于变化不是太大的非实时环境下使用,如果是实时环境,并且客户端要求实时更新而非间歇性更新的话,此方法慎用

[后续思路]:我们还可以将一些常用的东西进行缓存以后直接读取,免得再找数据库麻烦,个人认为文件操作要比数据库操作快(当然如果是分步式的数据库例外),如果有条件可以设置memcached等缓存机制,直接放在内存中肯定是最快的。
   我上面只是举了个例子将数据库存为数组,很多时候我们可能要应用到db->select的操作即数据库中的某个值存为前端显示的select选择项的操作,这点也是类例的。当然其它的概念还有很多,这里只是列出个思路。

   呵呵,还有些比较疯狂的想法(个人还没有实现),如果有可能所有的数据库中的数据都可以建立一次缓存(呵呵,这样要数据库就没用了,呵呵,数据库只能当做备份),并建立一个数据表数组,例如有数据库中有三个表 user,classroom, teacher .我们就建立一个数组$cache=array('user'=>1,'classroom'=>1,'teacher'=>1);
缓存所有的数据表,将数据表user的值进行改动时致 $cache['user']=0;然后在缓存机制中如果检测到cache中相应的值为0的话重新缓存数据否则就用原来的数据,呵呵。我们的列表,操作什么的就都可以针对此缓存来进行,分页,查找什么的也可以针对这个来进行。当然这种方法适用范围要比较注意,不然可能起到反效果。

  说了这么多,只是提出我的一些想法,各位大大多多指正呀。关键是看帖了后一定要回,不然俺都没啥激情了。

作者: leon_studio   发布时间: 2009-05-26

受教了~~~~~~~~~~~~

作者: phpquanchao   发布时间: 2009-05-26

精品文章。支持一个。

呵呵,万物皆可缓存,也许是的,
但我个人觉得,要看项目的特性和实际所需,
如果更新频繁的内容,
或者缓存过程涉及过多逻辑,
我还是主张该怎么样还是怎么样。
任何功能的使用我都觉得 有个度才好

作者: zzguo28   发布时间: 2009-05-26

强贴留名

作者: tdweb   发布时间: 2009-05-26

对,度,关键是一个度的把握!我也不赞成什么都用缓存,适量用是最好的!

作者: leon_studio   发布时间: 2009-05-27

真不错,我现在做项目也用到很多缓存,真的受教了.

作者: ckson   发布时间: 2009-06-03

其实现在的项目中多少都用到的了,TP里面也是支持缓存的啊。现在用的1.6RC1是支持FILE缓存的,不知道楼主的这种做法和TP支持的缓存有区别在哪里。是不是TP里面的是生产TEMP目录下的文件,是数据库的结构而不是内容而楼主的这个是生成内容,那么生产内容和静态页面的差距还是有的。内容的生成 数组和静态HTML我认为一样的,结果还是要生成文件啊。。。如果可以直接生成到内存中是最好的了。

其实从速度上看还是 大家讨论下 生成到内存中呵呵。。。。

作者: baddull   发布时间: 2009-06-06

内存成本太高了.....

作者: leon_studio   发布时间: 2009-06-07

使用xml作为数据库岂不是……

作者: cuish   发布时间: 2009-06-21

但我个人觉得,要看项目的特性和实际所需,

作者: di2ci   发布时间: 2009-06-28

TP 中的缓存都经过了 unserialize() 序列化。效率是极高的,为什么PHP 官方将$_SESSION 的数据都序列化了呢,就是这个道理。什么缓存成 HTML、xml 等等的形式都不值得一提。效率肯定打折扣的。

个人认为,用到缓存的地方通常是全站共享的数据作为缓冲比较好,打个例子做个购物网,产品分类肯定是核心部件。我们将它 unserialize()  序列化缓存。修改、新增、删除 产品分类是才触发更新缓存。这样,其他逻辑脚本需要用到产品分类,就直接读取缓存吧。而且,还可以用多种风格的CSS+div 样式来封装这个产品分类,输出千变万化的分类导航菜单。这样,就达到了一点缓存,多点共享的目的。

作者: jianjin712   发布时间: 2009-07-09

个人认为常用到的地方用缓存,内容页生成静态
至于搜索这样的,还是直接读数据库的好

作者: byyy521   发布时间: 2009-09-17

TP 中的缓存都经过了 unserialize() 序列化。效率是极高的,为什么PHP 官方将$_SESSION 的数据都序列化了呢,就是这个道理。什么缓存成 HTML、xml 等等的形式都不值得一提。效率肯定打折扣的。

个人认为,用到缓存 ...
jianjin712 发表于 2009-7-9 19:10
很同意老大的看法。不过,刚刚学习使用TP。不知道有没有办法,在项目ACTION执行之前就预先执行的ACTION?
也就是做一个初始作用。

作者: wind4   发布时间: 2010-05-15

高深,俺听不懂啊!

作者: Messi   发布时间: 2010-06-03

关键是看帖了后一定要回,不然俺都没啥激情了。

只看懂一半半

作者: nuan1989   发布时间: 2010-06-24

不是很明白,不过顶一下

作者: moore0903   发布时间: 2010-09-02

不知道这个缓存和静态缓存有何区别

作者: 541907190   发布时间: 2010-09-07

ecshop的缓存机制我觉得还不错,可以参考

作者: ayuelee   发布时间: 2010-09-13

不错不错 有想法..

作者: wclssdn   发布时间: 2010-09-15

......................

作者: a68460266   发布时间: 2011-06-08