前言
点赞其实是一个很有意思的功能。基本的设计思路有大致两种, 一种自然是用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进行分表
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]