电子市场由于数据较多,且区分主表、OEM表、正版软件表这三种数据,前一阵子老是反映里面有很多软件会重复,特别是搜索时,由于搜索三个表,所以造成数据重复。。。
主要表现在,因为存在分页,不可能把库都遍历一次来每个用户去一次重。。所以加缓存临时表显得刻不容缓。。
缓存表分二张:
第一张,用于记录缓存的ID还有过期时间等等信息。
-- 表的结构 sj_cache
CREATE TABLE IF NOT EXISTS sj_cache
(
id
int(11) NOT NULL AUTO_INCREMENT,
cache_id
varchar(32) NOT NULL,
created
int(11) NOT NULL,
expired
int(11) NOT NULL,
PRIMARY KEY (id
)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;
第二张,存放具体数据模板表
-- 表的结构 sj_cache_soft
CREATE TABLE IF NOT EXISTS sj_cache_soft
(
id
int(11) NOT NULL AUTO_INCREMENT,
cacheid
int(11) NOT NULL,
oemid
int(11) NOT NULL DEFAULT '0',
softname
varchar(255) DEFAULT NULL,
mips
smallint(6) NOT NULL DEFAULT '0',
x86
smallint(6) NOT NULL DEFAULT '0',
md5
varchar(32) DEFAULT NULL,
ico
varchar(255) DEFAULT NULL,
ico1
varchar(255) NOT NULL,
author
varchar(255) DEFAULT NULL,
description
varchar(255) DEFAULT NULL,
content
text,
star
smallint(6) DEFAULT '6',
resolution
varchar(50) NOT NULL,
platform
varchar(10) DEFAULT NULL,
packageid
varchar(70) DEFAULT NULL,
fullscreen
smallint(6) DEFAULT NULL,
minsdkversion
smallint(6) NOT NULL,
targetsdkversion
smallint(6) NOT NULL,
uses_permission
text NOT NULL,
PRIMARY KEY (id
),
KEY ix_packageid
(packageid
),
KEY oemid
(oemid
),
KEY x86
(x86
),
KEY mips
(mips
),
KEY cacheid
(cacheid
)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;
程序设计上如果把所有数据都存在这张表里。这个表会很大,做了下测试,开放一个小时,这个表的数据达到188万条记录,所以要实现分表。。
首先,得有一个函数来实现分表的创建与返回表名的过程 ,因为如果每次去库中查询表是否存在会严重影响性能,所以需要memcached缓存住那些已经存在了,具体实现过程如下。
/**
* 返回缓存表名以及创建表过程
* @param <type> 缓存KEYID
* @return string 缓存表名称
*/
function __getCacheTable($keyname=''){
if (!$keyname) return cache_soft;
//从mem中读入是否有该表名
$tbName=$this->mem->getCache($keyname);
if (!$tbName){
$tbName=cache_soft_.substr($keyname,-1);
//查询缓存表是否存在
$query=$this->db->query($sql=show tables like 'sj_$tbName');
$result=$this->db->fetch_array($query);
//如果不存在,则用模板表结构创建新的表
if (!$result){
$query=$this->db->query($sql=show create table sj_cache_soft);
$result=$this->db->fetch_array($query);
$sql=str_replace('sj_cache_soft','sj_'.$tbName,$result['Create Table']);
$this->db->query($sql);
//把表名放入mem缓存
$this->mem->setCache($keyname, $tbName,360000);
}
}
return $tbName;
}
应用过程片段。
for ($number = 0; $number <= 1;="" $number++)=""></=>
//缓存cacheid
$db_cache_id = substr(md5($rootid . $categoryid . $flag), 8, 16);
//缓存表名称
$db_cache_table=$this->__getCacheTable($db_cache_id);
//缓存查询
$dbCache = $this->selecttable('cache', '*', array(
'cache_id' => $db_cache_id
), 'limit 1');
if ($dbCache) {
$cacheid = $dbCache[0]['id'];
$this->data ['soft'] = array();
// 从缓存中开始分页查询
if (time () < $dbcache="" [0]['expired'])="">
$pagesize = $this->data ['CLIENT_SOFT_PAGESIZE'];
$orders = array(
'commend',
'hots',
'id'
);
$Order = $orders [$flag];
$sql = select * from . $this->tname($db_cache_table) . where cacheid={$cacheid};
if (!$flag) {
$sql .= and commend=1;
}
if (strpos($arch,'x86')!==false){
$sql .= and x86=1;
}
if (strpos($arch,'mips')!==false){
$sql .= and mips=1;
}
$query = str_replace(*, count(0), $sql);
$ret = $this->db->query($query);
$result = $this->db->fetch_row($ret);
$softcount = $result[0];
$pageCount = intval($softcount / $pagesize);
if ($softcount % $pagesize)
$pageCount++;
$this->data ['pCount'] = $pageCount;
$sql .= order by {$Order} desc;
$limit = LIMIT . ($page - 1) * $pagesize . ',' . $pagesize;
// 组装sql
$sql .= $limit;
if ($this->debug) var_dump($sql);
$ret = $this->db->query($sql);
while ($row = $this->db->fetch_array($ret)) {
if (!$row ['packageid'])
continue;
$this->data ['soft'][] = $row;
}
$isDbCache = true;
//如果缓存表数据返回,则跳出循环。
break;
}
}
//以下是从原数据查询结果
###########缓存处理中
$this->deletetable('cache', array('cache_id' => $db_cache_id));
$this->deletetable($db_cache_table, array('cacheid' => $cacheid));
$cacheid = $this->inserttable('cache', array('cache_id' => $db_cache_id, 'created' => time(), 'expired' => time() + 3600), 1);
// ########################################3
foreach ($iSql as $query) {
// 组装sql
$sql = $query . $orderby;
$ret = $this->db->query($sql);
while ($row = $this->db->fetch_array($ret)) {
if (!$row ['packageid'] or in_array($row['packageid'], $ExistPacks))
continue;
$this->data ['soft'][] = $row;
unset($row['id']);
$row['cacheid'] = $cacheid;
//把本条数据插入缓存表
$this->inserttable($db_cache_table, $row);
$ExistPacks[] = $row['packageid'];
}
}
}
这样下来系统的缓存会多达36个,这是以空间换取效率的一种办法,目前看来效率还是挺好的。。。