最近要寫一個類投票的系統:因爲訪問量可能會比較大,最好不直接使用mysql數據庫,徹底使用緩存的話,存在緩存失效等的風險,所以在mysql上面寫個緩存中間過渡:
1.memcachephp
按照個人習慣,確定是使用redis,可是公司目前這個項目線上尚未redis服務,只好湊合一下使用memcache。mysql
第一次的時候使用memcacheredis
這麼寫:
key爲'13453' value爲13920,sql
key爲'13454' value爲12989,
...數據庫
可是這麼一來的話就很差排序了,每次想排序,都要從緩存中取出不少個值。數組
第二次這麼寫:緩存
memcache中存儲了一個數組: 'pid' =>count數據結構
array(fetch
'13453' =>13920,ui
'13454'=>12989,
...
)
每次有人投票須要先取出該數組,而後再對應的pid上面加1,排序,再存入memcache中,代碼以下:
[php] view plaincopyprint?在CODE上查看代碼片派生到個人代碼片
/**
* @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);
}
[php] view plaincopyprint?在CODE上查看代碼片派生到個人代碼片
/**
* @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