使用redis實現(xiàn)互粉最近在寫api的時候要實現(xiàn)一個相互關(guān)注的功能,發(fā)現(xiàn)如果用mysql做查詢不是很理想, 所以想能不能用redis來實現(xiàn)這個功能,網(wǎng)上一搜有很多實現(xiàn)的方法,結(jié)合網(wǎng)上的博文,實現(xiàn)了自己的功能。
1.數(shù)據(jù)庫實現(xiàn)一下是數(shù)據(jù)庫的代碼,通過保存用戶的id和關(guān)注對象的id以及關(guān)注狀態(tài)來判斷用戶的關(guān)注列 表和粉絲列表,通過聯(lián)查獲取用戶的基本信息,入頭像、名稱。 'DROP TABLE IF EXISTS `shc_sns`;
CREATE TABLE `shc_sns` (
`sns_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id值',
`sns_frommid` int(11) NOT NULL COMMENT '會員id',
`sns_tomid` int(11) NOT NULL COMMENT '朋友id',
`sns_addtime` int(11) NOT NULL COMMENT '添加時間',
`sns_followstate` tinyint(1) NOT NULL DEFAULT '1' COMMENT '關(guān)注狀態(tài) 1為單方關(guān)注 2為雙方關(guān)注',
PRIMARY KEY (`sns_id`),
KEY `FROMMID` (`sns_frommid`) USING BTREE,
KEY `TOMID` (`sns_tomid`,`sns_frommid`) USING BTREE,
KEY `FRIEND_IDS` (`sns_tomid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=196 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='好友數(shù)據(jù)表';
'
2.使用redis實現(xiàn)redis提供了很多的類型,這里我們使用'zadd'添加有序集合來實現(xiàn)。如果不了解'zadd'命令的 可以點擊查看這個redis zdd命令 1.關(guān)注關(guān)注分為2個步驟,第一部是把對方加入到自己的關(guān)注list里面,第二步是將我寫入到對方 的粉絲中,這里score是通過時間戳生成的方便之后做分頁查詢,代碼如下 public function addFollowsFansById($data){
if(empty($data)) return false;
$data['sns_addtime'] = time();
if($data['sns_followstate'] == 1){
$result = $this->addFollowFan($data);
if($result){
$this->cache->redis->zAdd('shc_follow:'.$data['sns_frommid'],time(),$data['sns_tomid']);
$this->cache->redis->zAdd('shc_fans:'.$data['sns_tomid'],time(),$data['sns_frommid']);
}
return true;
}elseif($data['sns_followstate'] == 2){
$this->db->trans_begin();
$this->addFollowFan($data);
$this->editFollowFans(['sns_frommid'=>$data['sns_tomid'],'sns_tomid'=>$data['sns_frommid']],['sns_followstate'=>2]);
if($this->db->trans_status() === false){
$this->db->trans_rollback();
return false;
}else{
$this->db->trans_commit();
$this->cache->redis->zAdd('shc_follow:'.$data['sns_frommid'],time(),$data['sns_tomid']);
$this->cache->redis->zAdd('shc_fans:'.$data['sns_tomid'],time(),$data['sns_frommid']);
return true;
}
}else{
return false;
}
}
2.取消關(guān)注取消關(guān)注也分為2個步驟,第一步從我的關(guān)注列表中刪除對方,第二步從對方的粉絲列表中 刪除我,這里用redis的'zrem'來實現(xiàn)從有序集合中刪除記錄,redis zrem命令 public function deleteFollowFansById($user_id,$follow_id,$state){
if($state == 1){
$result = $this->deleteFollowFans(['sns_frommid'=>$user_id,'sns_tomid'=>$follow_id]);
if($result){
$this->cache->redis->zRem('shc_follow:'.$user_id,$follow_id);
$this->cache->redis->zRem('shc_fans:'.$follow_id,$user_id);
}
return true;
}elseif($state == 2){
$this->db->trans_begin();
$this->deleteFollowFans(['sns_frommid'=>$user_id,'sns_tomid'=>$follow_id]);
$this->editFollowFans(['sns_frommid'=>$follow_id,'sns_tomid'=>$user_id],['sns_followstate'=>1]);
if($this->db->trans_status() === false){
$this->db->trans_rollback();
return false;
}else{
$this->cache->redis->zRem('shc_follow:'.$user_id,$follow_id);
$this->cache->redis->zRem('shc_fans:'.$follow_id,$user_id);
$this->db->trans_commit();
return true;
}
}else{
return false;
}
}
3.查看關(guān)注列表、粉絲列表查看關(guān)注、粉絲列表原理一樣,用redis的'zrange','zrange'的形式如下
ZRANGE KEY START STOP
所以我們傳入要獲取的開始條數(shù)'curreng_page',以及要獲取的條數(shù) = 'current_page+page_size-1', 這里因為redis開始是1所以要-1,而數(shù)據(jù)庫是從0開始查詢,代碼如下: redis zrange命令 public function getFollowsListById($user_id,$limit=array()){
$follow_list = $this->cache->redis->zRevRange('shc_follow:'.$user_id,$limit['current_page'],$limit['current_page']+$limit['page_size']-1);
if($follow_list){
$member_list = $this->Member_Model->getMemberListByIdS($follow_list,'user_id,user_nickname,user_portrait');
if($member_list) return $member_list;
}else{
return $this->getFollowsListByDb(['a.sns_frommid'=>$user_id],'b.user_id,b.user_nickname,b.user_portrait',$limit);
}
}
4.關(guān)注、粉絲數(shù)量通過redis的'zcard'命令來返回有序集合的數(shù)量,也就是粉絲、關(guān)注的數(shù)量 5.關(guān)注狀態(tài)關(guān)注狀態(tài)分為3中類型,我當方面關(guān)注、你單方面關(guān)注、你我相互關(guān)注,所以很好理解,只要判斷有序集合中是否存在記錄就可以了, 這種可以用到redis的'zcore'命令,
ZSCORE 1:follow 2 #ture
ZSCORE 1:fans 2 #false
ZSCORE 1:follow 2 #false
ZSCORE 1:fans 2 #true
ZSCORE 1:follow 2 #true
ZSCORE 1:fans 2 #true
|