数据库方式实现实时排行榜

🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)

Sun Frame Banner

轻松高效的现代化开发体验

Sun Frame 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。

我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
您的支持是我们持续改进的动力。

🌟 亮点功能

  • 组件化开发:灵活选择,简化流程。
  • 高性能:通过异步日志和 Redis 缓存提升性能。
  • 易扩展:支持多种数据库和消息队列。

📦 spring cloud模块概览

  • Nacos 服务:高效的服务注册与发现。
  • Feign 远程调用:简化服务间通信。
  • 强大网关:路由与限流。

常用工具

  • 日志管理:异步处理与链路追踪。
  • Redis 集成:支持分布式锁与缓存。
  • Swagger 文档:便捷的 API 入口。
  • 测试支持:SpringBoot-Test 集成。
  • EasyCode:自定义EasyCode模板引擎,一键生成CRUD。

🔗 更多信息


1.排行榜的设计

1.实时榜单
1.数据库统计

现在数据库里面的 createby 字段。用户的标识是唯一的,那我们直接通过 group by 的形式统计 count。

select count(1),create_by from subject_info group by create_by limit 0,5;

数据量比较小,并发也比较小。这种方案是 ok 的。保证可以走到索引,返回速度快,不要产生慢 sql。

在数据库层面加一层缓存,接受一定的延时性。

2.redis 的 sorted set

有序集合,不允许重复的成员,然后每一个 key 都会包含一个 score 分数的概念。redis 根据分数可以帮助我们做从小到大,和从大到小的一个处理。

有序集合的 key 不可重复,score 重复。

它通过我们的一个哈希表来实现的,添加,删除,查找,复杂度 o(1) ,最大数量是 2 32 次方-1.

zadd

zrange

zincrby

zscore

这种的好处在于,完全不用和数据库做任何的交互,纯纯的通过缓存来做,速度非常快,要避免一些大 key 的问题。

2.非实时榜单

定时任务 xxl-job

统计数据库的数据形式,帮助我们统计完成后,直接写入缓存。缓存的外部的交互展示。

2.数据库方式实现

1.sun-club-subject模块
1.sun-club-application-controller
1.SubjectController.java
/**
 * 获取题目的贡献榜
 * @return
 */
@PostMapping("/getContributeList")
public Result<List<SubjectInfoDTO>> getContributeList() {
    try {
        // 打印日志
        if (log.isInfoEnabled()) {
            log.info("SubjectController getContributeList");
        }
        // 获取贡献榜
        List<SubjectInfoBO> boList = subjectInfoDomainService.getContributeList();
        // 转换BO为DTO
        List<SubjectInfoDTO> dtoList = SubjectInfoDTOConverter.INSTANCE.convertBO2DTO(boList);
        return Result.ok(dtoList);

    } catch (Exception e) {
        log.error("SubjectController getContributeList error", e);
        return Result.fail("获取贡献榜失败");
    }
}
2.SubjectInfoDTO.java 新增三个属性
/**
 * 创建人昵称
 */
private String createUser;

/**
 * 创建人头像
 */
private String createUserAvatar;

/**
 * 题目数量
 */
private Integer subjectCount;
2.sun-club-domain
1.SubjectInfoDomainService.java
/**
 * 获取贡献榜
 * @return
 */
List<SubjectInfoBO> getContributeList();
2.SubjectInfoDomainServiceImpl.java
@Override
public List<SubjectInfoBO> getContributeList() {
    // 从数据库中查询题目信息的list
    List<SubjectInfo> subjectInfoList = subjectInfoService.getContributeList();
    // 如果查不到就直接返回空
    if (CollectionUtils.isEmpty(subjectInfoList)) {
        return Collections.emptyList();
    }
    // 如果查到了,就封装到BO中
    List<SubjectInfoBO> boList = new LinkedList<>();
    subjectInfoList.forEach(subjectInfo -> {
        SubjectInfoBO subjectInfoBO = new SubjectInfoBO();
        subjectInfoBO.setSubjectCount(subjectInfo.getSubjectCount());
        // rpc调用根据createBy来查询该用户的昵称和头像
        String createdBy = subjectInfo.getCreatedBy();
        UserInfo userInfo = userRpc.getUserInfo(createdBy);
        subjectInfoBO.setCreateUser(userInfo.getNickName());
        subjectInfoBO.setCreateUserAvatar(userInfo.getAvater());
        boList.add(subjectInfoBO);
    });

    return boList;
}
3.SubjectInfoBO.java 新增三个属性
/**
 * 创建人昵称
 */
private String createUser;

/**
 * 创建人头像
 */
private String createUserAvatar;

/**
 * 题目数量
 */
private Integer subjectCount;
3.sun-club-infra
1.SubjectInfoService.java
/**
 * 获取贡献榜
 * @return
 */
List<SubjectInfo> getContributeList();
2.SubjectInfoServiceImpl.java
    /**
     * 获取贡献榜
     * @return
     */
    @Override
    public List<SubjectInfo> getContributeList() {
        return this.subjectInfoDao.getContributeList();
    }
3.SubjectInfoDao.java
/**
 * 获取贡献榜
 * @return
 */
List<SubjectInfo> getContributeList();
4.SubjectInfoDao.xml 注意count(1)要加别名才能与entity对应
<!-- 根据createdBy分组查询每组的题目数量 -->
<select id="getContributeList" resultMap="SubjectInfoMap">
    select count(1) as subjectCount,
        created_by
    from subject_info
    where is_deleted = 0
      and created_by is not null
    group by created_by
    limit 0, 5
</select>
5.UserInfo.java 新增头像属性
package com.sunxiansheng.subject.infra.eneity;

import lombok.Data;

/**
 * Description:
 * @Author sun
 * @Create 2024/6/16 13:47
 * @Version 1.0
 */
@Data
public class UserInfo {

    private String userName;

    private String nickName;

    private String avater;
}
6.UserRpc.java 设置头像属性

image-20240621175440547

2.测试

image-20240621175609199

  • 41
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S-X-S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值