redis zset 多值排序

最近面试老被问到ZSet相关的排序题,平时也没相关的经验,一问一个不吱声。抽有点时间,自己尝试去想了一种解决方案。

ZSet相关常用命令

添加成员

ZADD [Key] [Score] [Member]
//例 向班级a里面插入小明的80分
ZADD   a     80     xiaoming

有序获取

//从低到高获取指定区间的人员
ZRANGE [Key] [Start] [Stop] [WITHSCORES
//例 获取班级a里面所有人的分数 
ZRANGE     a    0        -1     WITHSCORES 
//例 获取班级a里面分数从低到高10个人的分数 
ZRANGE     a    0         9     WITHSCORES
//从高到低获取指定区间的人员 
ZREVRANGE [Key] [Start] [Stop] [WITHSCORES]

 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。

你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。 

TIPS: 如果分数相同的话,Redis会按照Member的词典顺序排序。比如 xiaoming和 xiaoli 都是80分,但是他两中的 l < m ,会导致分数从小到大 xiaoli 排在 xiaoming 前面。

增加分数 

ZINCRBY [Key]  [Score_Step]  [Member]
//例 发现班级a里面小明分数统计错误,需要再加10分
ZINCRBY a 10 xiaoming

 

 Redis场景设计

某公司举办了一次小型售卖公司周边礼物的活动,需要你实时统计这场活动商品售卖数量前x的商品。

  用zset实现也比较简单,以 活动ID 为Key , 商品ID 为 Member,售卖额为 Score。每次商品售卖量增加时调用 ZINCRBY 原子增加 Score 即可。

ZADD    [活动ID] [售卖数量]      [商品ID]
ZINCRBY [活动ID] 1 [商品ID]

一般真实场景没这么简单,比如在此基础上产品肯要求售卖数量相同时,再按照商品价格从低到高排序,相同价格的再按照最新售卖时间从小到大排序。 

   可以尝试将Score分段,比如定制一个标准Score数值模板 10000000000000 (举个例子,结合业务情况自己设置),将蓝色部分当最新售卖时间排序值,绿色部分是价格排序值,红色部分是真实销售量。售卖量增加只需要加红色部分即可

  时间区间的排序值可以利用时间戳计算,但是Score精度只有16位,此时可以将活动创建时间当成时间戳起始值、减少时间戳精确度(以小时级)等方式减少位数。

  

  售卖一个商品之后,每次更新前先查一下redis里面的值,计算一下时间差值再 ZINCRBY 增加 Score。

    1、先取出商品对应的score

    ZSCORE [活动ID] [商品ID]

    2、计算时间部分的变更量(假设变更了1小时)

    7200 =  time.now().Unix()-time.Unix(score%1000000, 0)

    3、对score进行变更

    ZINCRBY [活动ID]   1000007200   [商品ID]     

       

 

posted @ 2024-07-06 01:19  FCmmmmmm  阅读(8)  评论(0编辑  收藏  举报