最近要写一个类投票的系统:由于访问量可能会比较大,不能直接使用mysql数据库,完全使用缓存的话,存在缓存失效等的风险,因此在mysql上面写个缓存中间过渡:
1.memcache
按照我的习惯,肯定是使用redis,但是公司目前这个项目线上还没有redis服务,只好凑合一下使用memcache。
第一次的时候使用memcache
这么写:
key为'13453' value为13920,
key为'13454' value为12989,
...
但是这么一来的话就不好排序了,每次想排序,都要从缓存中取出很多个值。
第二次这么写:
memcache中存储了一个数组: 'pid' =>count
array(
'13453' =>13920,
'13454'=>12989,
...
)
每次有人投票需要先取出该数组,然后再对应的pid上面加1,排序,再存入memcache中,代码如下:
/**
* @brief 从memcache中取出数据,并相应增加一,然后排序
*/
private function _addCount($uid) {
if(empty($uid)) {
return false;
}
$mc_key = "MEM_KEY_SORT";
$list = self::memcache()->get($mc_key);
$list[$uid]++;
if(empty($list)) {
$list = $this->_getCount();//数据不存在则查询数据库(group by)
}
asort($list);
$ret = self::memcache()->set($mc_key, $list);
}
/**
* @brief 从数据库获取投票次数
* @return array('uid' => '次数')
*/
private function _getCount() {
$sql = "select pid,count(pid) as count from `tmp_ssjj_zqwz` group by pid";
$query = self::db()->query($sql);
while(($row = self::db()->fetch_array($query))!==FALSE) {
$list[$row['pid']] = $row['count'];
}
return $list;
}
数据结构如下:
CREATE TABLE `tmp_ssjj_zqwz` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`uid` int(11) NOT NULL COMMENT '投票id',
`type` int(11) NOT NULL DEFAULT '0' COMMENT '投票类型',
`pid` int(11) NOT NULL DEFAULT '0' COMMENT '被投票id',
PRIMARY KEY (`id`),
UNIQUE KEY `unique_uid_type` (`uid`,`type`),
KEY `index_pid` (`pid`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=gbk;
加上索引,使用group by来统计数据:
select pid,count(pid) as count from `tmp_ssjj_zqwz` group by pid
2.使用redis中的有序集合,直接解决问题:
value为'13453' score为13920,
value为'13454' score为12989,
...一段代码,直接搞定:
$list= $redis->zRange($_GET['key'], 0, -1);
最后,我是redis的fans。比较支持redis