我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于redis实现的点赞功能设计思路详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于redis实现的点赞功能设计思路详解

前言

点赞其实是一个很有意思的功能。基本的设计思路有大致两种, 一种自然是用mysql等

数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysql等。

直接写入Mysql

直接写入Mysql是最简单的做法。

做两个表即可,

1、post_like

记录文章被赞的次数,已有多少人赞过这种数据就可以直接从表中查到;

2、user_like_post

记录用户赞过了哪些文章, 当打开文章列表时,显示的有没有赞过的数据就在这里面;

缺点

1、数据库读写压力大

热门文章会有很多用户点赞,甚至是短时间内被大量点赞, 直接操作数据库从长久来看不是很理想的做法。

redis存储随后批量刷回数据库

redis主要的特点就是快, 毕竟主要数据都在内存嘛;

另外为啥我选择redis而不是memcache的主要原因在于redis支持更多的数据类型, 例如hash, set, zset等。

下面具体的会用到这几个类型。

优点

1、性能高

2、缓解数据库读写压力

其实我更多的在于缓解写压力, 真的读压力, 通过mysql主从甚至通过加入redis对热点数据做缓存都可以解决,

写压力对于前面的方案确实是不大好使。

缺点

1、开发复杂

这个比直接写mysql的方案要复杂很多, 需要考虑的地方也很多;

2、不能保证数据安全性

redis挂掉的时候会丢失数据, 同时不及时同步redis中的数据, 可能会在redis内存置换的时候被淘汰掉;

不过对于我们点赞而已, 稍微丢失一点数据问题不大;

具体设计

Mysql设计

这一块和写入写mysql是一样的,毕竟是要落地存储的。

所以还是同样的需要post_like, user_like_post这两表存储文章被点赞的个数(等统计), 用户对那些文章点了赞(取消赞)。

这两表分别通过post_id, user_id进行关联。

redis设计部分:

post_set

在redis中弄一个set存放所有被点赞的文章

post_user_like_set_{$post_id}

对每个post以post_id作为key, 搞一个set存放所有对该post点赞的用户;

post_user_like_{$post_id}_{$user_id}

将每个用户对每个post的点赞情况放到一个hash里面去, hash的字段就

随意跟进需求来处理就行了。

为啥用hash

只所以用hash是因为完全可以用hash来存储一个点赞的对象, 对应数据库的一行记录。

当然有同学会说用key, value也可以, 将所有的数据序列化(json_encode等)

后全部放到value里面去。 反复序列化也是一个很大的开销不是, hash可以很

方便的修改某个字段, 而序列化和反序列化的操作。

post_{$post_id}_counter

对每个post维护一个计数器, 用来记录当前在redis中的点赞数,

这里我们只用counter记录尚未同步到mysql中的点赞数(可以为负), 每次

刷回mysql中时将counter中的数据和数据库已有的赞数相加即可。

用户点赞/取消赞

获取user_id, post_id, 查询该用户是否已经点过赞, 已点过则不允许再次点赞,

或者设计为前端允许用户点, 只是后台不重复计算;

这里需要注意的是用户点赞的记录可能在数据库中, 也可能在缓存中, 所以查询的时候

缓存和数据库都要查询, 缓存没有再查询数据库。

将用户的点赞/取消赞的情况记录在redis中, 具体为:

1、写入post_set

将post_id写入post_set

2、写入post_user_like_set_{$post_id}

将user_id写入post_user_like_set_{$post_id}

3、写入post_user_like_{$post_id}_{$user_id}

将用户点赞数据, 例如赞状态, post_id, user_id, ctime(操作时间), mtime(修改时间)写入post_user_like_{$post_id}_{$user_id}中

4、更新post_{$post_id}_counter

更新post_{$post_id}_counter, 这里的更新稍晚复杂一点, 需要和前面一样先获取当前用户是否对这个post点过赞

如果点过, 并且本次是取消赞, counter减一, 如果没点过, 本次是点赞, counter加一。

如果原来是取消赞的情况, 本次是点赞, counter加一。

同步刷回数据库

循环从post_set中pop出来一个post_id至到空

根据{$post_id} , 每次从post_user_like_set_{$post_id}中pop出来一个user_id直到空

根据post_id, user_id, 直接获取对应的hash表的内容(post_user_like_{$post_id}_{$user_id}

将hash表中的数据写入user_like_post表中

将post_{$post_id}_counter中的数据和post_like中的数据相加, 将结果写入到post_like表中

页面展示

1、查询用户点赞情况

前面已经说过, 需要同时查询redis和mysql

2、查询post点赞统计

同样需要查询redis中的post_{$post_id}_counter和mysql的post_like表, 并将两者相加

得到的结果才是正确的结果

总结

解决了mysql读写的问题

但没有针对用户量较大的场景考虑分表的设计, 可以考虑针对user_id或者post_id进行分表

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对编程网的支持。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于redis实现的点赞功能设计思路详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于redis实现的点赞功能设计思路详解

前言 点赞其实是一个很有意思的功能。基本的设计思路有大致两种, 一种自然是用mysql等 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysql等。 直接写入Mysql 直接写
2022-06-04

如何设计一个高效的MySQL表结构来实现视频点赞功能?

如何设计一个高效的MySQL表结构来实现视频点赞功能?背景在现代社交媒体平台中,点赞是用户对喜欢的内容表示认可和支持的一种常见方式。对于一个视频平台来说,实现视频点赞功能是非常重要的。本文将介绍如何设计一个高效的MySQL表结构来实现视频点
如何设计一个高效的MySQL表结构来实现视频点赞功能?
2023-10-31

Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能详解

本文实例讲述了Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能。分享给大家供大家参考,具体如下:android SDK中带有这样类似的例子,但是那个还是静态数据,没有实际应用价值,参考意义不大
2023-05-30

编程热搜

目录