使用Redis实现高效的帖子投票(点赞)功能设计与实现
一、Redis中的数据结构与适用场景
在设计点赞功能时,Redis的多种数据结构能够帮助我们实现不同的需求:
- ZSet(有序集合):ZSet允许为每个成员指定一个分数,支持按分数排序。我们可以用它来按时间、评分存储和排序帖子。
- Set(集合):用于存储不重复的数据,如帖子所属的社区或投票的用户ID。
- Hash(哈希表):用于存储帖子或用户的详细信息,如用户的ID、用户名等。
二、功能设计与实现
1. 按时间和评分存储帖子
我们使用Redis的ZSet
按时间和评分分别存储帖子信息:
-
按时间存储帖子:将帖子的发布时间作为分数,将帖子ID作为ZSet的成员。例如:
ZADD post:time 1598170163.05 309568 ZADD post:time 1598180322.60 323585 ZADD post:time 1598190123.35 556736
这段代码将帖子的发布时间存储在
post:time
ZSet中,便于按时间顺序展示帖子。 -
按评分存储帖子:我们也可以使用ZSet来按评分存储帖子。评分越高,帖子展示优先级越高。例如:
ZADD post:score 1598180322.60 323585 ZADD post:score 1598180586.05 309568 ZADD post:score 1598227323.35 556736
这段代码将帖子按评分进行存储,评分高的帖子会优先展示。
2. 存储用户投票信息
每个帖子需要记录用户的点赞和点踩操作。我们为每个帖子创建一个独立的ZSet来存储用户投票情况,ZSet中的每个成员为用户ID,分数表示该用户的投票类型(1代表点赞,-1代表点踩)。
例如,用户 31095628 对帖子 556736 进行了点赞,用户 31235835 进行了点踩:
ZADD post:voted:556736 1 31095628
ZADD post:voted:556736 -1 31235835
通过这样的设计,帖子 556736 的用户投票信息便得到了完整的记录。
3. 社区管理功能
对于不同社区下的帖子,我们可以使用Set
存储每个社区的帖子ID,以便于对不同社区的帖子进行管理和展示。假设社区ID为 2143,有多个帖子属于该社区,可以通过以下命令存储:
SADD community:2143 308569
SADD community:2143 313485
SADD community:2143 546726
此时,社区 2143 下的帖子集合便存储完毕。
4. 按社区获取帖子并排序
通过Redis命令ZINTERSTORE
,我们可以交叉获取某个社区中的帖子,并按评分进行排序。该命令可以将社区内的帖子ID集合与按评分排序的ZSet结合,返回指定社区下的高分帖子。
例如,我们希望获取社区 2143 内的热门帖子,可以通过以下命令实现:
ZINTERSTORE post:score:2143 2 community:2143 post:score
这段代码将社区 2143 下的帖子按评分交叉存储到新的ZSet中,方便进一步排序和展示。
三、Redis命令与操作示例
-
ZADD:用于向ZSet中添加帖子信息,如按时间和评分存储帖子:
ZADD post:time 1598170163.05 309568 ZADD post:score 1598180322.60 323585
-
ZRANGEBYSCORE:按评分范围获取帖子列表。例如,获取所有点赞(1分)的用户:
ZRANGEBYSCORE post:voted:556736 1 1
-
ZREVRANGE:按评分降序获取帖子列表:
ZREVRANGE post:score 0 9 WITHSCORES
-
SADD:将帖子添加到某个社区中:
SADD community:2143 308569
-
ZINTERSTORE:获取某个社区内按评分排序的帖子:
ZINTERSTORE post:score:2143 2 community:2143 post:score
四、实现步骤总结
- 帖子存储:使用
ZSet
按时间和评分存储帖子,便于不同展示场景(如按时间展示、按评分展示)。 - 投票记录:每个帖子创建一个ZSet来记录用户的点赞和点踩,分数为1表示点赞,-1表示点踩。
- 社区帖子管理:使用
Set
存储不同社区的帖子,并结合ZSet
对其进行按评分排序和展示。 - 热门帖子展示:通过
ZINTERSTORE
结合社区与评分的ZSet,实现社区内帖子按评分排序的功能。