MST

星途 面试题库

面试题:如何基于Redis有序集合设计一个支持多维度排名的系统?

现在需要设计一个复杂的电商商品排名系统,不仅要根据销量排名,还要考虑好评率、上架时间等多个维度进行综合排名。请详细描述如何利用Redis有序集合来实现这个多维度排名系统,包括数据结构设计、更新策略以及查询逻辑等方面。
18.5万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

数据结构设计

  1. 商品数据存储
    • 使用Redis的Hash数据结构来存储每个商品的详细信息。例如,对于商品ID为product:1,可以这样存储:
    HSET product:1 id 1
    HSET product:1 name "商品名称"
    HSET product:1 sales 100
    HSET product:1 positive_rate 0.95
    HSET product:1 shelf_time 1677638400  # 时间戳,假设为上架时间
    
  2. 有序集合设计
    • 创建一个有序集合,例如命名为product_rank,来存储商品的综合排名。
    • 有序集合的成员(member)为商品ID,分值(score)为综合排名得分。计算综合排名得分时,需要根据销量、好评率、上架时间等多个维度进行加权计算。假设销量权重为w1,好评率权重为w2,上架时间权重为w3,则综合得分score的计算公式可以是:
    score = w1 * sales + w2 * positive_rate + w3 * (1 / (current_time - shelf_time + 1))
    
    • 这里current_time是当前时间戳,(1 / (current_time - shelf_time + 1))的设计是为了让上架时间越近的商品得分越高,加1是为了避免分母为0的情况。

更新策略

  1. 销量更新
    • 当商品销量发生变化时,首先更新商品Hash中的销量字段。例如,商品ID为product:1销量增加10:
    HINCRBY product:1 sales 10
    
    • 然后重新计算综合得分并更新有序集合中的分值。假设已经计算出新的综合得分new_score
    ZADD product_rank new_score product:1
    
  2. 好评率更新
    • 好评率发生变化时,同样先更新商品Hash中的好评率字段。例如,商品ID为product:1好评率更新为0.96:
    HSET product:1 positive_rate 0.96
    
    • 接着重新计算综合得分并更新有序集合中的分值:
    ZADD product_rank new_score product:1
    
  3. 上架时间更新(极少发生,如重新上架)
    • 更新商品Hash中的上架时间字段,例如商品ID为product:1重新上架,设置新的上架时间new_shelf_time
    HSET product:1 shelf_time new_shelf_time
    
    • 重新计算综合得分并更新有序集合中的分值:
    ZADD product_rank new_score product:1
    

查询逻辑

  1. 获取排名靠前的商品
    • 使用ZRANGE命令获取排名靠前的商品。例如,获取排名前10的商品:
    ZRANGE product_rank 0 9 WITHSCORES
    
    • 该命令返回有序集合中排名从0(最小分值)到9(共10个元素)的商品ID及其对应的综合得分。
  2. 获取某个商品的排名
    • 使用ZRANK命令获取某个商品的排名。例如,获取商品ID为product:1的排名:
    ZRANK product_rank product:1
    
    • 如果返回结果为nil,表示该商品不在有序集合中;否则返回该商品的排名(从0开始)。
  3. 分页查询
    • 假设每页显示page_size个商品,要查询第page_num页的商品,可以使用ZRANGE命令结合偏移量计算。偏移量offset = (page_num - 1) * page_size,例如:
    ZRANGE product_rank offset (offset + page_size - 1) WITHSCORES
    
    • 这样可以获取第page_num页的商品及其综合得分。