Zen-cart中提供了对数据库查询结果进行缓存功能。数据库查询结果缓存原理非常简单,对查询的SQL语句取散列值,然后把查询返回的结果关联这个散列值保存起来,当有同样的查询时就从保存的结果中直接返回(前提是没有过期)。
首先看缓存类的框架:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
class cache extends base {
//判断缓存是否存在,$zf_cachetime用来指定缓存时间,对应过期的缓存当然不能判断为存在
function sql_cache_exists($zf_query, $zf_cachetime) {
global $db;
$zp_cache_name = $this->cache_generate_cache_name($zf_query);
switch (SQL_CACHE_METHOD) {
case 'file':
//................
break;
case 'database':
//................
break;
case 'memory':
return false;
break;
case 'none':
default:
return false;
break;
}
}
//判断缓存是否过期
function sql_cache_is_expired($zf_query, $zf_cachetime) {
}
//马上过期
function sql_cache_expire_now($zf_query) {
}
//保存缓存
function sql_cache_store($zf_query, $zf_result_array) {
}
//读取缓存
function sql_cache_read($zf_query) {
}
//刷新缓存
function sql_cache_flush_cache() {
}
//生成缓存名
function cache_generate_cache_name($zf_query) {
}
}
|
从源代码可以看出,Zen-cart只支持把缓存保存到file和database中,保存到database中是比较少用的,在高并发的情况下,更加倾向把结果保存到memory中,不过Zen-cart没有提供实现(可做二次开发)。
另外,保存的方式使用常量SQL_CACHE_METHOD指定,这个值需要在配置文件中指定:
1
2
3
|
#includes/configure.php
define('SQL_CACHE_METHOD', 'file');
define('DIR_FS_SQL_CACHE', 'D:/www/web/z151.com/public_html/cache');
|
如果SQL_CACHE_METHOD为none,那么根本不会进行缓存。
注:SQL_CACHE_METHOD在安装Zen-cart时就会提示把缓存的的方法,是file还是database,默认是none。
缓存对象的生成是在环境初始化时进行的:
1
2
3
|
$autoLoadConfig[30][] = array('autoType'=>'classInstantiate',
'className'=>'cache',
'objectName'=>'zc_cache');
|
这个对象的名字叫zc_cache,它是环境初始化中首先构建的对象之一(在它之前是数据库初始化)。
那么这个对象何时会用到?实际上就是在触发SELECT查询时这个对象就会被使用。
1
2
3
4
5
6
7
8
|
##includes/clssses/db/mysql/query_factory.php
class queryFactory extends base {
function Execute($zf_sql, $zf_limit = false, $zf_cache = false, $zf_cachetime=0) {
//....
global $zc_cache;
}
}
|
Execute方法是Zen-cart中对数据库操作封装最核心的方法,zf_sql是要执行的SQL(不仅限于查询),zf_limit限制返回的结果数量,zf_cache表示是否缓存查询结果(只对SELECT查询起作用),zf_cachetime指定缓存时间。
目前Zen-cart默认代码应用查询缓存的有如下地方:
1
2
3
4
|
##includes/classes/category_tree.php
//...
$categories = $db->Execute($categories_query, '', true, 150);
//...
|
另一个地方是读取配置文件:
1
2
3
4
|
##includes/init_includes/init_db_config_read.php
$use_cache = (isset($_GET['nocache']) ? false : true ) ;
$configuration = $db->Execute('select configuration_key as cfgkey, configuration_value as cfgvalue
from ' . TABLE_CONFIGURATION, '', $use_cache, 150);
|
这两个地方读取的数据都是经常不改变的,所以缓存起来有必要。特别是配置表,如果每次都查询数据库,并发量一大,就会耗费大量的数据库资源,而这些消耗是完全没有必要的。
另外,虽然Zen-cart中的cache类是用来缓存数据库查询结果的,但是并不意味着你只能用它来缓存数据库查询结果,你完成可以把某个变量缓存起来,比如某个变量每次请求时都要重新构建,而已内容都是一样的,这种情况就非常合适缓存,只是你需要使用这个变量之前首先要判断缓存是否存在,这个操作控制起来非常简单。
举例:
1
2
3
4
5
|
$cs = $db->Execute("select * from countries");
while(!$cs->EOF){
echo $cs->fields['country_name']."<br />";
$cs->MoveNext();
}
|
使用压力测试工具对这对代码进行测试,获取结果。
然后对带数据缓存的版本进行测试:
1
2
3
4
5
|
$cs = $db->Execute("select * from countries",0,true,2000);
while(!$cs->EOF){
echo $cs->fields['country_name']."<br />";
$cs->MoveNext();
}
|
对比结果就能得出结论。
在高并发环境中,对于频繁访问的数据,如果能对数据进行缓存,那么数据库的压力下减是非常明显的。如果并发量很小,几乎感觉不到缓存有什么作用。
(责任编辑:最模板) |