点赞其实是一个很有意思的功能。基本的设计思路有大致两种, 一种自然是用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进行分表

基于redis实现的点赞功能设计思路详解的更多相关文章

  1. 高并发架构系列:Redis并发竞争key的解决方案详解

    https://blog.csdn.net/ChenRui_yz/article/details/85096418 https://blog.csdn.net/ChenRui_yz/article/l ...

  2. 基于双向BiLstm神经网络的中文分词详解及源码

    基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...

  3. Java编程配置思路详解

    Java编程配置思路详解 SpringBoot虽然提供了很多优秀的starter帮助我们快速开发,可实际生产环境的特殊性,我们依然需要对默认整合配置做自定义操作,提高程序的可控性,虽然你配的不一定比官 ...

  4. redis cluster管理工具redis-trib.rb详解

    redis cluster管理工具redis-trib.rb详解 来源 http://weizijun.cn/2016/01/08/redis%20cluster%E7%AE%A1%E7%90%86% ...

  5. 分布式-技术专区-Redis并发竞争key的解决方案详解

    Redis缓存的高性能有目共睹,应用的场景也是非常广泛,但是在高并发的场景下,也会出现问题:缓存击穿.缓存雪崩.缓存和数据一致性,以及今天要谈到的缓存并发竞争.这里的并发指的是多个redis的clie ...

  6. BaseAdapter自定义适配器——思路详解

    BaseAdapter自定义适配器——思路详解 引言: Adapter用来把数据绑定到扩展了AdapterView类的视图组.系统自带了几个原生的Adapter. 由于原生的Adapter视图功能太少 ...

  7. 基于集合成工控机Ubuntu系统安装分区详解

    基于集合成工控机Ubuntu系统安装分区详解 硬件描述:双核的CPU,128G的固态硬盘 软件描述:使用Ubuntu12.04系统,内核3.8.0-29版本,QT4.8.1版本 1.新建分区表 /de ...

  8. Redis for Windows(C#缓存)配置文件详解

    Redis for Windows(C#缓存)配置文件详解   前言 在上一篇文章中主要介绍了Redis在Windows平台下的下载安装和简单使用http://www.cnblogs.com/aehy ...

  9. spring基于通用Dao的多数据源配置详解【ds1】

    spring基于通用Dao的多数据源配置详解 有时候在一个项目中会连接多个数据库,需要在spring中配置多个数据源,最近就遇到了这个问题,由于我的项目之前是基于通用Dao的,配置的时候问题不断,这种 ...

随机推荐

  1. reportComplaints.js: Uncaught TypeError: Cannot read property 'message' of undefined

    vonic 中遇到这么个问题, 一直提示我未定义, 可是明明有定义 var tab={ message:{ number:'', title:'' } } var id= { template: '# ...

  2. git 使用及常用命令介绍

    一.git 常用命令 git clone 地址 克隆项目 git status 查看当前状态 git add 文件或文件夹 (加入本地暂存目录) git commit -m "注释" ...

  3. node.js—Buffer类(二进制数据处理模块)

    Buffer类概述 一个用于更好的操作二进制数据的类 我们在操作文件或者网络数据的时候,其实操作的就是二进制数据流 Node为我们提供了一个更加方便的去操作这种数据流的类 Buffer,他是一个全局的 ...

  4. 【vue】在移动端使用better-scroll 实现滚动效果

    安装依赖:(c)npm install better-scroll --save 引入: import BScroll from 'better-scroll' 格式: var obj = new B ...

  5. .net core redis 驱动推荐,为什么不使用 StackExchange.Redis 转发 https://www.cnblogs.com/kellynic/p/9325816.html

    前言 本人从事 .netcore 转型已两年有余,对 .net core 颇有好感,这一切得益于优秀的语法.框架设计. 2006年开始使用 .net 2.0,从 asp.net 到 winform 到 ...

  6. 使用 OAuth2-Server-php 搭建 OAuth2 Server

    Yii 有很多 extension 可以使用,在查看了 Yii 官网上提供的与 OAuth 相关的扩展后,发现了几个 OAuth2 的客户端扩展,但是并没有找到可以作为 OAuth2 Server 的 ...

  7. Long类型参数传到前端精度丢失的解决方案

        由于公司数据库表的id是利用雪花算法生成的,所以实体类里面定义的数据类型为Long.但是这个数据传到前端时,发生了精度丢失的现象.本文记录了从java后端的角度如何解决这个精度丢失的问题,便于 ...

  8. web安全:通俗易懂,以实例讲述破解网站的原理及如何进行防护!如何让网站变得更安全。

    本篇以我自己的网站为例来通俗易懂的讲述网站的常见漏洞,如何防止网站被入侵,如何让网站更安全. 要想足够安全,首先得知道其中的道理. 本文例子通俗易懂,主要讲述了 各种漏洞 的原理及防护,相比网上其它的 ...

  9. 一篇 SpringData+JPA 总结

    概述 SpringData,Spring 的一个子项目,用于简化数据库访问,支持 NoSQL 和关系数据库存储 SpringData 项目所支持 NoSQL 存储 MongDB(文档数据库) Neo4 ...

  10. Visual studio 2015 Community 安装过程中遇到问题的终极解决

    早就有给自己电脑升级VS的想法,可是安装过程并不顺利,一直拖到现在,昨天下定决心,把遇到的问题一个个解决,终于安装成功了,将安装过程中遇到的问题和解决方法记录一下. 需要说明一下的是,不同的电脑环境可 ...