用Redis做数据排名

1.背景

用Redis做数据缓存用的比较多,大家都能熟练使用String和Hash结构去存储数据,今天讲下如何使用ZSet来做数据排名。

假设场景是需要按天存储全国城市的得分数据,可以查询前十名的城市排名。

这个case可以使用传统关系型数据库做,设计一个表存储城市名、得分、录入时间,查询的时候按时间过滤某天的数据然后排序取前10条,这样做的缺点是存储的数据会越来越多,后面的查询会越来越慢。选择ZSet可以自动排序,并且key设置过期时间后,可以仅仅保存最近多少天的数据。

2.数据结构设计

  • key:选择日期为key,比如20230924
  • member:用城市名称作为value,比如changsha
  • score:计算出来的值

3.接口设计

3.1 新增数据接口

该接口负责将城市得分放到每日的key中。

java 复制代码
@GetMapping("/redis/set")
    public void set(@RequestParam("key") String key, @RequestParam("city") String city,@RequestParam("value") String value){
        Long total = redisTemplate.opsForZSet().zCard(key);

        if (total >= 10) {
            return;
        }

        redisTemplate.opsForZSet().add(key, city, Double.parseDouble(value));
        if (redisTemplate.hasKey(key) && 0 == total) {
            redisTemplate.expire(key, 7, TimeUnit.DAYS);
        }
    }
3.2 查询城市得分排名接口
java 复制代码
@GetMapping("/redis/get")
    public String get(@RequestParam("key") String key){
        Set<ZSetOperations.TypedTuple<Object>> typedTuples = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 9);
        List<CityRank> list = new ArrayList<>();
        typedTuples.stream().forEach(
                tuple -> {
                    CityRank cityRank = new CityRank();
                    cityRank.setScore(tuple.getScore());
                    cityRank.setValue(tuple.getValue().toString());
                    list.add(cityRank);
                });
        return JSON.toJSONString(list);
    }

4.测试

使用第一个接口录入数据,得到的结果:

使用第二个接口查询城市排名:

java 复制代码
[{"score":770.0,"value":"nanchang"},{"score":750.0,"value":"guangzhou"},{"score":550.0,"value":"xiamen"},{"score":500.0,"value":"nanjing"}]

5.总结

在使用ZSet的时候设置Key过期时间想了好久,如果在Key没有创建的时候对其设置过期时间是无效的,因此在添加完数据后做了一个判断,必须有Key,并且里面只有一个元素这是就设置过期时间,后面增加数据不会再走此逻辑,防止延长过期时间导致Key一直存在。希望朋友们看了我的文章针对数据排名展示这块有更好的想法和我交流。

相关推荐
AI人工智能+电脑小能手16 分钟前
【大白话说Java面试题 第93题】【Mysql篇】第23题:从查找速度来看,聚集索引和非聚集索引哪个更快?
java·开发语言·数据库·mysql·面试
WPF工业上位机33 分钟前
YXGK.FakeVM数据库示例
jvm·数据库·oracle
牛奔1 小时前
如何让 GORM 打印 SQL 语句?三种方式全解析
数据库·sql
XWalnut1 小时前
Redis从入门到精通
数据库·redis·缓存
andafaAPS1 小时前
安达发|工艺品aps自动排产排程排单软件:告别生产“一团乱麻“
大数据·数据库·人工智能·安达发aps·计划排产软件·自动排单软件
zt1985q1 小时前
本地部署源代码管理解决方案 Bitbucket Data Center 并实现外部访问
运维·服务器·数据库·网络协议·postgresql·源代码管理
xiaofeichaichai1 小时前
Service Worker、PWA 与 Web Worker — 离线缓存与主线程算力分离
前端·缓存
一只专注api接口开发的技术猿2 小时前
OpenClaw 对接淘宝商品 API,低成本实现全天候选品监控|附可运行 Python 实操代码
大数据·开发语言·数据库·python
爱喝水的鱼丶2 小时前
SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇)第三篇:SAP接口对接开发:实现数据的实时/批量校验交互
运维·数据库·学习·性能优化·sap·abap·经验交流
真香号3 小时前
记一次生产RocketMQ消息积压消费慢的排查与解决
数据库·rocketmq·java-rocketmq