mysql 和redis实现点赞功能
点赞是非常常见的功能,普通mysql也可以实现,但遇到高并发性能不是很好,目前好的方式是利用redis缓存来实现,从而减轻数据库压力。
news_user_like_set_{$news_id} 集合用来存放该文章下点赞用户的`id`。
news_user_like_{$news_id}_{$user_id} HASH用来存放点赞记录,如点赞状态,点赞时间,更新点赞时间,用户ID,文章ID等。
news_{$counts}_counts 用来记录redis中文章的点赞数量,点赞加1,取消点赞减1。
list_news 列表用来存放news_id队列数据。
流程:
1.当客户端触发点赞是user_id news_id zan_type 发送服务器。(说明:我的需求里面有文章点赞,评论点赞,词条点赞,所以要有一个类型标注下
2.服务器拿到参数去redis 查询是否有news_user_like_{$news_id}_{$user_id}
redis 有,则得到的状态取反 没有则去mysql查 ,mysql 有,得到状态取反,没有则redis新增一个news_user_like_{$news_id}_{$user_id} ,点赞状态设置1
3.根据点赞状态给news_{$counts}_counts 加一或减一
4.把user_id 加入news_user_like_set_{$news_id}
5.把news_id加入 list_news 队列 返回文章点赞数和当前点赞状态
看不懂上面的就看贴的代码,不懂可以评论区提问,看到会解答
<?php
namespace app\news\controller;
use app\login\model\News;
use think\facade\Cache;
use think\facade\Db;
/**
* Class LikeCount
* @package app\news\controller
* 点赞类
*/
class LikeCount extends News
{
private $redis = null;
private $user_id;//用户id
private $news_id;//文章id
private $status;//点赞状态
private $news_set;//集合存放所有点赞的文章ID
private $news_user_like;//hash存放用户点赞记录
private $news_user_like_set;//集合存放该文章下点赞用户ID
private $list_news;//队列存放news_id
private $news_counts;//文章点赞数
private $time;
private $zan_type;
public function __construct()
{
$this->redis = Cache::store('redis');
$this->news_set = 'news_set';
$this->list_news = 'list_news';
}
/**
* 点赞操作
*
* 点赞数据存在hash中,每个用户点赞信息存一个hash
* 集合set存储当前文章下的点赞用户,news_user_like_set_{news_id}
* news_{news_id}_counts 存储的点赞数
* 队列 list_news 存储的是文章id
*
* 1.redis获取点赞信息news_user_like_{news_id}_{user_id},得到点赞状态
* 2.如上面没获取到,mysql查询获取点赞信息,得到点赞状态,都没有说明当前用户未点赞过,设置状态为1
* 3.存储点赞信息,如redis有点赞信息,则更新hash的update_time和status字段,没有新增hash信息,news_id,user_id,zan_type,create_time,update_time,status
* 4.存储文章下的点赞用户id到集合set
* 5.更新点赞数,根据点赞状态判断,0 取消点赞-1 1点赞+1
* 6.存储news_id到队列
* 7.返回点赞数 redis+mysql
*
* @param string $user_id 用户id
* @param string $news_id 文章id
* @param int $zan_type 点赞类型
* @return bool
*/
public function giveFavour($user_id = '', $news_id = '', $zan_type = 0)
{
$user_id = 1;
$news_id = 754395;
$zan_type = 1;
if (empty($user_id) || empty($news_id) || empty($zan_type)) {
return false;
}
$th