首页 > 数据库 >基于Redis的ZSET数据类型实现点赞排行榜

基于Redis的ZSET数据类型实现点赞排行榜

时间:2023-10-31 23:31:39浏览次数:27  
标签:ZSET 数据类型 top5 Redis 用户 score key 点赞 id

点赞排行榜(ZSET实现)

基于Redis的ZSET数据类型实现点赞排行榜_Redis

实现原理:

使用redis的zset进行存储,score为当前时间,值为用户ID

public Result likeBlog(Long id) {
// 1.获取登录用户
Long userId = UserHolder.getUser().getId();
// 2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY + id;
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
if (score == null) {
    // 3.如果未点赞,可以点赞
    // 3.1.数据库点赞数 + 1
    boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();
    // 3.2.保存用户到Redis的set集合  zadd key value score
    if (isSuccess) {
        stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());
    }
} else {
    // 4.如果已点赞,取消点赞
    // 4.1.数据库点赞数 -1
    boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();
    // 4.2.把用户从Redis的set集合移除
    if (isSuccess) {
        stringRedisTemplate.opsForZSet().remove(key, userId.toString());
    }
}
return Result.ok();
}
获取点赞排行榜前5名
String key = BLOG_LIKED_KEY + id;
// 1.查询top5的点赞用户 zrange key 0 4
Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
if (top5 == null || top5.isEmpty()) {
    return Result.ok(Collections.emptyList());
}
// 2.解析出其中的用户id
List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
String idStr = StrUtil.join(",", ids);
// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)
List<UserDTO> userDTOS = userService.query()
.in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list()
.stream()
.map(user -> BeanUtil.copyProperties(user, UserDTO.class))
.collect(Collectors.toList());
// 4.返回
return Result.ok(userDTOS);
MySQL中的Field函数

field() 函数:是将查询的结果集按照指定顺序排序。

格式: FIELD(str,str1,str2,str3,...)

什么时候用: 想让某几个特定的字段值放在最后,用field()函数。

解释: str是字段名字,字符串str1,str2,str3等等,是该字段的值。

函数意思: 匹配到str1,将其放到结果集最后返回。

详细解析: 当字段值没有匹配到str1,str2或者str3的时候,按照正常排序;当匹配到这些的时候,会把没有匹配的值放到最前面,匹配到的放到后边,并且以写的顺序排序返回结果集。

场景: 数据库有字段model,代表手机型号,值有很多,和更多型号;现在根据model字段排序,查询结果集中,’‘更多型号’’ 必须放最后。

ORDER BY FIELD(model,'更多型号')
1

sql中排序比较常见,我们常用的排序语句是这两个。

select * from 表名 order by 字段名 asc //升序

select * from 表名 order by 字段名 desc //降序

标签:ZSET,数据类型,top5,Redis,用户,score,key,点赞,id
From: https://blog.51cto.com/AmbitionGarden/8114977

相关文章

  • java 基本数据类型和引用数据类型
    ......
  • Redisson在日常开发过程中的使用
    使用BitSet实现日期连续签到@GetMapping("/user/sign/{id}")publicResult<String>userSign(@PathVariable("id")Longid,@RequestParam(value="date",required=false)......
  • Redis持久化机制
    持久化机制通常来说,应该同时使用两种持久化方案,以保证数据安全:如果数据不敏感,且可以从其他地方重新生成,可以关闭持久化如果数据比较重要,且能够承受几分钟的数据丢失,比如缓存等,只需要使用RDB即可如果是用做内存数据,要使用Redis的持久化,建议是RDB和AOF都开启如果只用AO......
  • Redis部署架构
    部署架构单节点(Single)优点架构简单,部署方便高性价比:缓存使用时无需备用节点(单实例可用性可以用supervisor或crontab保证),当然为了满足业务的高可用性,也可以牺牲一个备用节点,但同时刻只有一个实例对外提供服务高性能缺点不保证数据的可靠性在缓存使用,进......
  • 浅析Redis大Key
    一、背景在京东到家购物车系统中,用户基于门店能够对商品进行加车操作。用户与门店商品使用Redis的Hash类型存储,如下代码块所示。不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此Key就会越来越大,从而影响线上业务。userPin:{storeId:{门店下加车的所有商品......
  • windows设置redis开机启动
    最近遇到了个问题,需要在windows中使用redis,但是redis没有开机启动,需要每次通过命令行进行启动,所以选择了设置redis开机启动。另外cmd窗口启动redis,如果不小心关掉了cnd,redis会跟着停掉,很不方便进入redis文件夹,打开cmd,输入命令:redis-server.exe--service-installredis.window......
  • Redis学习
    Redis数据结构Redis数据类型常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合),随着Redis版本的更新,后面又支持了四种数据类型:BitMap(2.2版新增)、HyperLogLog(2.8版新增)、GEO(3.2版新增)、Stream(5.0版新增)。应用场景String类型的应用场景:缓存对......
  • PHPStudy 安装tp8 php8.2.9 安装XDbug、redis扩展安装XDbug扩展vscode断点:
    一、PhpStudy升级PHP版本,安装PHP8.2操作步骤1.1、官网下载最新的php版本打开Windows版的官网下载,地址:https://windows.php.net/download/ 页面上有不同的PHP版本,这里我们下载的是64位nts版的PHP8.2.9。1.2、解压下载的文件将下载的文件php-8.2.9-nts-Win32-vs16-x64.zip,移到PhpS......
  • Opencascad开发(C++)-数据类型转换-Shape、Verterx和gp_pnt的转化
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录1、前言2、TopoDS_Shape与TopoDS_Vertex的转换2.1TopoDS_Shape到TopoDS_Vertex2.2TopoDS_Vertex到TopoDS_Shape3、TopoDS_Vertex与gp_Pnt3.1TopoDS_Vertex到gp_Pnt3.2gp_Pnt到TopoDS_Vertex1、前言在Open......
  • Redis集群模式incr保证原子性的原理
    1.主要是redis的key会解析到固定的主机上,比如集群上有host1,host2,host3;然后key1可能会解析后发现是要发到host2上,则在host2正常的情况下(有点像kafkarebalance;consumer处理哪些分区),key1会一直在host2上进行操作;因此在redis集群正常情况下不会出现对key1第一次incr是在host2,第二次......