项目亮点之排行榜

排行榜

参考链接

数据库实现

order by关键字

最简单的实现方式,通常性能不会很好

ORDER BY 关键字可以使查询返回的「结果集」按照指定的列进行排序,可以按照某「一列」排序或者同时按照「多列」进行排序,排序的顺序可以是「升序」或者「降序」。

SELECT column_name,column_name
FROM table_name
ORDER BY column_name,column_name ASC|DESC;

窗口函数

窗口函数中的顺序函数,通常性能也不会很好

窗口函数 效果
ROW_NUMBER() 顺序排序
RANK() 并列排序,会跳过重复的序号,比如序号为1、1、3
DENSE_RANK() 并列排序,不会跳过重复的序号,比如序号为1、1、2

Redis实现

zset

value 是一个集合,且可以看出这个集合是有序的。集合中的每一个 member 都有一个 score,然后按照这个 score 进行降序排序。

  • 添加member

    zadd key score member [score member ...]
    
  • 增加 member 的 score

    zincrby key increment member
    
  • 获取 member 排名

    默认是升序排列

    zrank/zrevrank key member
    
  • 返回指定排名范围内的 member

    zrange/zrevrange key start end [withscores]
    

拓展

好友范围排行榜&好友点赞

  • 好友范围思路
    • 不建议直接维护不同的zset,性能消耗过大;可以延迟加载,当用户请求查看排行榜的时候,再去根据用户的好友关系,循环获取好友的步数,生成排行榜。
  • 点赞思路
    • 我的朋友发的动态用list,可以在朋友发的时候加到我的List,也可以我登录的时候取拉
    • 然后是点赞列表,因为点赞不能重复而且是有顺序的,可以用set来维护某条动态的点赞列表(set的名称就是动态id,值为点赞列表)
    • 点击用户头像会看到用户的信息,一般用String(key的名称为用户的id,值为用户信息的json数据)
    • 是否点赞,可以使用hash类型,因为hash中判断是否存在某个key的时间复杂度是O(1)

七日排行榜

对一段日期的排行榜做并集,得到一段日期的数据的总体排行榜数据;

对一段日期的排行榜做交集,得到一段日期的数据的总体排行榜数据(排除期间中断上榜的信息);

  • 获取交集/并集

    zinterstore/zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max] 
    
    • zinterstore/zunionstore其实就是交集/并集
    • destination 将交集/并集的结果保存到这个键中
    • numkeys 需要做交集/并集的集合的个数
    • key [key ...] 具体参与交集/并集的集合
    • weights weight [weight ...] 每个参与计算的集合的权重。在做交集/并集计算时,每个集合中的 member 会把自己的 score 乘以这个权重,默认为 1。
    • aggregate sum|min|max 对于各个集合中的相同元素是 sum(求和)、min(取最小值)还是max(取最大值),默认为 sum。

亿级排行榜

分治算法处理,将单个排行榜分为多个排行榜处理(桶),但落点并不均匀,设计算法解决马太效应(强者愈强,弱者愈弱)

非实时排行榜

利用定时任务,获取统计完的排行榜数据,将数据缓存至临时表(或缓存);当客户端调用获取排行榜接口时直接返回临时表(或缓存)数据。

使用redis的string做缓存,自定义key,value为json数据

posted @ 2022-07-22 23:17  Faetbwac  阅读(32)  评论(0编辑  收藏  举报