使用Redis实现文章阅读量、收藏、点赞数量记录功能

news2024/11/27 4:32:18

目录

    • 一、前言
    • 二、业务分析
    • 三、Redis数据结构选择分析和实现
      • 3.1、三个数据缓存都分别使用 字符串 结构计数器存储对应数量值
      • 3.2、三个数据缓存使用一个 Hash 结构存储
      • 3.3、阅读量使用字符串结构计算器,收藏和点赞分别使用 Set 集合存储
    • 四、总结

一、前言

      在博客中会显示文章阅读量、收藏、点赞数量这些值都是经常变化的,收藏和点赞用户还是可以取消的会记录用户标记状态。如果每一次用户查看博客都从数据库中检索这些数据那数据库开销是非常大的,这个时候就需要使用到缓存来存储这些信息。
在这里插入图片描述

需要看Redis命令可以查看:
Redis常用命令集:https://blog.csdn.net/weixin_44606481/article/details/133672258

二、业务分析

      在这三个数据中,阅读量和用户没有关系不用存储用户和文章的关系,但是收藏和点赞和用户就是有关的,每个用户对同一篇文章只能收藏一次和点赞一次,并且可以取消,是有状态的数据,针对这两种不同类型的业务选择的数据结构也不同,实现方法也有很多种这里分析其中几个。

三、Redis数据结构选择分析和实现

      这里不会过多分析数据库相关方面设计,重点分析Redis中应该如何存储这些数据可以高效使用,阅读量是一个持续自增的值和其它业务无关,在数据表中用一个字段记录即可,但是收藏和点赞需要一个对应业务和用户的关联表来记录关系,每次查询时都要查询关联表统计出文章被多少用户收藏和点赞,还要判断当前查看文章的用户是否有收藏和点赞,当然数量信息我们也可以存储某个记录表中,但是每次查询都打到数据库压力还是挺大的,数据库资源很宝贵,这些信息统计好后存储在缓存中会是一个不错的选择。

3.1、三个数据缓存都分别使用 字符串 结构计数器存储对应数量值

鉴于上面所说,这里我们将阅读量、收藏、点赞数量使用三个字符串结构存储,不同业务操作对应key即可,还要注意这些数据入数据库操作。

  • 1、Key定义规则

    • 阅读量key:article:readcount:文章id
    • 收藏数量key:article:collectcount:文章id
    • 点赞数量key:article:likecount:文章id
  • 2、代码实现
    这里直接使用计数器操作即可,每次有对应操作只要对具体key做自增或者自减即可,假设文章id=1

    ## 文章每次被阅读,文章阅读量自增1
    127.0.0.1:6379> incr article:readcount:1
    ## 文章每次被收藏,文章收藏数量自增1
    127.0.0.1:6379> incr article:collectcount:1
    ## 文章每次被点赞,文章点赞数量自增1
    127.0.0.1:6379> incr article:likecount:1
    
    ## 文章每次被取消收藏,文章收藏数量自减1
    127.0.0.1:6379> decr article:collectcount:1
    ## 文章每次被取消点赞,文章点赞数量自减1
    127.0.0.1:6379> decr article:likecount:1
    
    ## 获取文章阅读量、收藏、点赞数量
    127.0.0.1:6379> get article:readcount:1
    127.0.0.1:6379> get article:collectcount:1
    127.0.0.1:6379> get article:likecount:1
    
  • 3、优点

    • 实现简单、能减轻统计查询时的数据库压力
  • 4、不足点

    • 需要使用非常多的key,一篇文章就要使用三个key,而且每次查看文章都需要请求Redis三次才能获取到这三个数量值,对Redis资源开销比较大,可以使用Hash结构优化。

3.2、三个数据缓存使用一个 Hash 结构存储

针对3.1中因为需要使用非常多的key,一篇文章就要使用三个key,而且每次查看文章都需要请求Redis三次才能获取到这三个数量值,对Redis资源开销比较大,这里可以使用Hash结构优化。

  • 1、Key定义规则

    • 文章阅读、收藏、点赞Hash结构 key:article:count:文章id
    • Hash结构中阅读量key:readcount
    • Hash结构中收藏数量key:collectcount
    • Hash结构中点赞数量key:likecount
  • 2、代码实现
    这里直接Hash 结构操作即可,每次有对应操作只要对具体Hash结构中的key做自增或者自减即可,假设文章id=1

    ## 文章每次被阅读,文章阅读量自增1
    127.0.0.1:6379> hincrby article:count:1 readcount 1
    ## 文章每次被收藏,文章收藏数量自增1
    127.0.0.1:6379> hincrby article:count:1 collectcount 1
    ## 文章每次被点赞,文章点赞数量自增1
    127.0.0.1:6379> hincrby article:count:1 likecount 1
    
    ## 文章每次被取消收藏,文章收藏数量自减1
    127.0.0.1:6379> hincrby article:count:1 collectcount -1
    ## 文章每次被取消点赞,文章点赞数量自减1
    127.0.0.1:6379> hincrby article:count:1 likecount -1
    
    ## 获取文章阅读量、收藏、点赞数量
    127.0.0.1:6379> hgetall article:count:1
    
  • 3、优点

    • 相比于3.1中实现简单、能有效减低Redis资源开销
  • 4、不足点

    • 还是有一点问题没有解决,如果要查询阅读用户和文章的收藏和点赞关系,那么还是要查询数据库,数据库压力还是比较大,在下面3.3中会针对这个问题使用 Set 集合解决。

3.3、阅读量使用字符串结构计算器,收藏和点赞分别使用 Set 集合存储

为了解决查询阅读用户和文章的收藏和点赞关系,还需要查询数据库问题,这里采用Set集合来存储文章收藏点赞和用户的关联关系。

  • 1、Key定义规则

    • 阅读量key:article:readcount:文章id
    • 收藏数量Set key:article:collectuser:文章id
    • 点赞数量Set key:article:likeuser:文章id
  • 2、代码实现
    阅读量还是普通结构和3.1一致,收藏和点赞使用Set集合存储文章和用户对应关系,每次收藏点赞时将用户ID加入到对应Set集合中,假设文章id=1。

    ## 文章每次被阅读,文章阅读量自增1
    127.0.0.1:6379> incr article:readcount:1
    ## 文章每次被收藏,将用户ID加入到文章收藏的Set集合中,假设用户ID为1001
    127.0.0.1:6379> sadd article:collectuser:1 1001
    ## 文章每次被点赞,将用户ID加入到文章点赞的Set集合中,假设用户ID为1001
    127.0.0.1:6379> sadd article:likeuser:1 1001
    
    ## 文章每次被取消收藏,将用户ID从文章收藏的Set集合中删除
    127.0.0.1:6379> srem article:collectuser:1 1001
    ## 文章每次被取消点赞,将用户ID从文章点赞的Set集合中删除
    127.0.0.1:6379> srem article:likeuser:1 1001
    
    ## 获取文章阅读量、收藏、点赞数量
    ### 获取阅读量
    127.0.0.1:6379> get article:readcount:1
    ### 获取收藏数量
    127.0.0.1:6379> scard article:collectuser:1
    ### 获取点赞数量
    127.0.0.1:6379> scard article:likeuser:1
    
    ## 获取当前阅读用户是否收藏、点赞当前文章
    ### 获取用户是否收藏当前文章
    127.0.0.1:6379> sismember article:collectuser:1 1001
    ### 获取用户是否点赞当前文章
    127.0.0.1:6379> sismember article:likeuser:1 1001
    
  • 3、优点

    • 对于阅读量、收藏、点赞相关所有的查询操作都可以通过Redis获取,大大降低了数据库压力,并且还会再Redis中维护文章和用户的收藏、点赞关系,查询用户是否收藏点赞也不要再去查询数据库。
  • 4、不足点

    • 事情都有两面性,使用Redis来缓存这些信息虽然能大大提升系统整体性能,但是可能出现缓存与数据库数据不一致问题,还有缓存过期时间问题,如果一篇文章一个月才被访问一次那么不可能一直缓存这篇文章的信息,需要设置一个删除时间,要想比较完善的实现那么设计这个功能复杂度是成倍增长的。

四、总结

      实现方式还有很多,比如在3.3中还能使用Hash结构去维护阅读量、收藏、点赞的数量信息,收藏和点赞与用户关联信息放入对应Set集合中,这样就不用每次都去不同的key中获取对应数量信息了,一个Hash全搞定,最终要选择什么方案还是结合项目实际情况来决定的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1188479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIA-PPPOE原理与配置

PPPOE原理与配置 实验拓扑图实现步骤家庭网关 AR201PPPOE客户端( ISP光猫)PPPOE服务器(ISP路由器) 实验拓扑图 实现步骤 家庭网关 AR201 E0/0/0-7为LAN口(二层接口)E0/0/8为WAN口(三层接口&am…

【每日一题】2258. 逃离火灾-2023.11.9

题目: 2258. 逃离火灾 给你一个下标从 0 开始大小为 m x n 的二维整数数组 grid ,它表示一个网格图。每个格子为下面 3 个值之一: 0 表示草地。1 表示着火的格子。2 表示一座墙,你跟火都不能通过这个格子。 一开始你在最左上角…

LeetCode【78. 子集】

78. 子集 中等 2.2K 相关企业 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…

Frp内网穿透部署

Frp内网穿透部署记录windows为例 A固定外网IP服务器一台(可以映射端口)B内网PC一台,可上外网 A固定外网IP服务器一台(可以映射端口) B内网PC一台,可上外网 GO语言:https://golang.org/doc/ins…

如何用CHAT 写会后总结

问CHAT:阐述参加IMS系统培训课程的收益和不学的损失。 CHAT 回复: 参加IMS系统培训课程的收益: 1. 提升技能和知识:通过参加IMS系统培训课程,你可以学习到刚新的信息技术和知识,增强你的技能和经验&…

UART编程(寄存器)

1. 串口编程步骤 1.1 看原理图确定引脚 有很多串口,使用哪一个?看原理图确定 1.2 配置引脚为UART功能 至少用到发送、接收引脚:txd、rxd 需要把这些引脚配置为UART功能,并使能UART模块 1.3 设置串口参数 有哪些参数&#xf…

Leecode刷题【hot100】盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。 示例…

linux生成code文件

1. 设置core文件路径在当前工作目录 echo "core-%e-%p-%t" > /proc/sys/kernel/core_pattern 具体参数 %s - insert signal that caused the coredump into the filename 添加导致产生core的信号 %t - insert UNIX time that the coredump occurred into filen…

使用 Wireshark 抓包工具快速分析 IoT 物联网终端设备的网络通信行为

当你进行 IoT 物联网开发过程中,终端-MQTT 服务器-业务系统-App 全链路联调时往往难以快速定位问题:终端可能未正常发出消息报文,也可能在网络传输中丢失,也可能被 MQTT 服务器限流丢弃,或者业务系统处理异常而丢失。此…

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】

Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】 文章目录 Centos7安装宝塔面板8.0.3并实现公网远程登录宝塔面板【内网穿透】一、使用官网一键安装命令安装宝塔二、简单配置宝塔,内网穿透三、使用固定公网地址访问宝塔 宝塔面板作为建站运维工具&…

flink1.18.0 sql-client报错

报错 Flink SQL> select * from t1; [ERROR] Could not execute SQL statement. Reason: org.apache.flink.table.api.ValidationException: Could not find any factory for identifier kafka that implements org.apache.flink.table.factories.DynamicTableFactory in t…

如何搭建一个自定义UI框架的Playground(一)

文章目录 初衷需求技术选型详细设计(一)1.业务设计2.交互设计3.程序设计3.1 游戏生命周期设计3.2 UI界面管理设计 初衷 想要比较系统、深入地了解游戏UI框架的设计与开发,就需要自己实践去开发一个可以预览的UI项目,但是目前没有…

OpenTiny Vue 组件库支持 Vue2.7 啦!

之前 OpenTiny 发布了一篇 Vue2 升级 Vue3 的文章。 🖖少年,该升级 Vue3 了! 里面提到使用了 ElementUI 的 Vue2 项目,可以通过 TinyVue 和 gogocode 快速升级到 Vue3 项目。 有朋友评论替换button出错了,并且贴出了…

K8S篇之etcd数据备份与恢复

一、etcd备份与恢复 基本了解: 1、k8s 使用etcd数据库实时存储集群中的数据,安全起见,一定要备份。 2、备份只需要在一个节点上备份就可以了,每个节点上的数据是同步的;但是数据恢复是需要在每个节点上进行。 3、etcd…

性能测试从0到1

性能测试概念 我们经常看到的性能测试概念,有人或称之为性能策略,或称之为性能方法,或称之为性能场景分类,大概可以看到性能测试、负载测试、压力测试、强度测试等一堆专有名词的解释。 针对这些概念,我不知道你看到…

AppWeb 身份验证绕过漏洞 (CVE-2018-8715)漏洞复现

漏洞描述 AppWeb 是一个嵌入式 Web 服务器,基于由 Embedthis Software LLC 开发和维护的开源 GPL 协议。它是用C / C编写的,几乎可以在任何现代操作系统上运行。当然,它旨在为嵌入式设备提供一个 Web 应用程序容器。 AppWeb 可以配置为身份…

lua 时间差功能概略

简介 在进行程序设计过程中,经常需要对某些函数、某些程序片断从开始运行到运行结束所耗费的时间进行一些量化。这种量化实际上就是计算时间差。 获取函数耗时情景如下: function time_used() --开始计时-- do something at here. --结束计时--时间差&…

kubernetes集群编排——k8s资源监控

资源限制 上传镜像 [rootk8s2 limit]# vim limit.yaml apiVersion: v1 kind: Pod metadata:name: memory-demo spec:containers:- name: memory-demoimage: stressargs:- --vm- "1"- --vm-bytes- 200Mresources:requests:memory: 50Milimits:memory: 100Mi [rootk8s2…

Kotlin系列之注解详解

目录 注解:file:JvmName 注解:JvmField 注解:JvmOverloads 注解:JvmStatic 注解:JvmMultifileClass 注解:JvmSynthetic 注解:file:JvmName file:JvmName(“XXX”) 放在类的最顶层&#x…

基于51单片机蓝牙智能控制风扇-proteus仿真-源程序

基于51单片机蓝牙智能控制风扇-proteus仿真-源程序 一、系统方案 1、本设计采用51单片机作为主控器。 2、DS18B20采集温度值送到液晶1602显示。 3、按键设置上下限,自动模式,低于下限,风扇不启动,下限到上限之间,风扇1…