手把手教你用Redis 实现点赞功能并且与数据库同步
一、背景介绍
在网站或应用中,点赞功能是常见的交互方式,它的实现需要进行大量的计数和数据存储。如果全部使用数据库进行点赞数量统计和查询功能相关操作,会对数据库造成不小的压力,从而影响整个应用的性能。
为了解决这个问题,我们可以使用Redis来实现点赞功能。Redis是一种内存数据存储系统,因此在执行计数操作时非常快,加速了点赞操作以及点赞数量的查询。
此外,使用Redis还可以将点赞数量等数据存储在内存中,不会占用数据库存储空间。
二、准备工作
在开始本教程之前,你需要先准备好以下工具:
- Redis数据库
- PHP程序环境和相关扩展,例如phpredis扩展
三、代码实现
本文以PHP语言为例,详细讲解如何使用Redis来实现点赞功能。
1. 初始化
在实现点赞功能前,需要先连接Redis数据库,并进行初始化设置。
// 连接Redis数据库
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// 设置Redis所使用的数据库编号
$redis->select(0);
2. 点赞操作
点赞操作分为两个步骤:增加点赞数量和记录用户点赞信息。
// 用户点赞操作
function upVote($userId, $articleId)
{
// 增加点赞数量
$redis->hincrby('vote', $articleId, 1);
// 记录用户点赞信息
$redis->sadd('upvote:'.$articleId, $userId);
}
在增加点赞数量时,使用Redis的hincrby
方法实现。hincrby
方法会根据所传入的key和字段名称在Redis中进行自增操作,并将结果返回。
在记录用户点赞信息时,使用Redis的sadd
方法实现。sadd
方法会将指定的值添加到指定的集合中,如果已存在,则无法重复添加。
3. 取消点赞操作
取消点赞操作也分为两个步骤:减少点赞数量和删除用户点赞信息。
// 用户取消点赞操作
function cancelVote($userId, $articleId)
{
// 减少点赞数量
$redis->hincrby('vote', $articleId, -1);
// 删除用户点赞信息
$redis->srem('upvote:'.$articleId, $userId);
}
与点赞操作相反,在减少点赞数量时,使用Redis的hincrby
方法,但是在这里需要传递负数值。在删除用户点赞信息时,使用Redis的srem
方法,它会从指定的集合中删除指定的值。
4. 获取点赞数量和用户点赞状态
获取点赞数量和用户点赞状态的操作都很简单,只需要使用相应的Redis命令即可。
// 获取点赞数量
function getVoteCount($articleId)
{
return intval($redis->hget('vote', $articleId));
}
// 获取用户点赞状态
function isVoted($userId, $articleId)
{
return $redis->sismember('upvote:'.$articleId, $userId);
}
在获取点赞数量时,使用Redis的hget
方法获取对应field的值,并且需要将返回结果转换为整型。
在获取用户点赞状态时,使用Redis的sismember
方法判断指定的元素是否属于集合。
四、与数据库同步
虽然使用Redis来实现点赞功能可以有效地减轻数据库压力,但是这样做需要与数据库进行同步操作,以保证应用数据的一致性。
在本例中,我们可以使用MySQL数据库来保存点赞信息,并使用Redis来更新点赞数量。
1. MySQL表结构定义
创建一个名为vote
的数据表,用于保存文章点赞信息。
CREATE TABLE `vote` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`user_id` int(11) NOT NULL COMMENT '用户ID',
`article_id` int(11) NOT NULL COMMENT '文章ID',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章点赞记录表';
2. 记录点赞信息到MySQL
在点赞操作和取消点赞操作前增加一些代码,将点赞信息记录到MySQL数据库中。
// 记录点赞信息到MySQL数据库
function addVoteToDB($userId, $articleId)
{
$stmt = $conn->prepare("INSERT INTO vote(user_id, article_id) VALUES (?, ?)");
$stmt->bind_param('ii', $userId, $articleId);
$stmt->execute();
}
// 用户点赞操作
function upVote($userId, $articleId)
{
// 记录点赞信息到MySQL数据库
addVoteToDB($userId, $articleId);
// 增加点赞数量
$redis->hincrby('vote', $articleId, 1);
// 记录用户点赞信息
$redis->sadd('upvote:'.$articleId, $userId);
}
// 取消点赞操作
function cancelVote($userId, $articleId)
{
// 删除点赞信息从MySQL数据库中
deleteVoteFromDB($userId, $articleId);
// 减少点赞数量
$redis->hincrby('vote', $articleId, -1);
// 删除用户点赞信息
$redis->srem('upvote:'.$articleId, $userId);
}
在记录点赞信息到MySQL数据库时,使用MySQL的prepared statements语法,防止SQL注入攻击。
3. 从MySQL同步点赞信息到Redis
当Redis重新启动或者缓存数据被清空时,可以通过从MySQL数据库中获取点赞信息,然后同步到Redis中来保证数据一致性。
// Redis重新连接后,从MySQL数据库同步点赞信息
function syncVoteFromDB()
{
$query = "SELECT article_id, COUNT(*) as count FROM vote GROUP BY article_id";
$result = $conn->query($query);
while ($row = mysqli_fetch_assoc($result)) {
$redis->hset('vote', $row['article_id'], intval($row['count']));
}
}
在从MySQL中读取点赞信息时,使用MySQL的GROUP BY
语句和COUNT
函数对点赞数量进行统计。
最后,将从MySQL中读取的数据同步到Redis中,使用Redis的hset
方法设置Redis Hash数据类型中的field-value对应关系。
五、总结
本文通过实现点赞功能为例,详细讲解了如何使用Redis来加速应用的计数、查询等操作,并与MySQL数据库同步点赞信息。这种方式不仅可以减轻数据库的负载,还可以提高应用的性能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:手把手教你用Redis 实现点赞功能并且与数据库同步 - Python技术站