最近在用 redis 的 SortedSet 做积分排行榜,降序排列。 SortedSet 默认同样的积分后达到的排名靠前(降序) 即假如我现在有个 key 为rank的里面有如下 member:
m1:10
m2:20
按降序排的话应该是:m2>m1
假如这时候又来了 m3 ,积分也是 20 分,按照 SortedSet 的排序应该是:m3>m2>m1
但我们很多时候需求是 同样的积分谁先达到谁排名靠前,即想要的结果应该是:m2>m3>m1
各位有这样的需求吗?都是怎么处理的呢?
1
bbao 2017-04-17 12:15:54 +08:00
增加一个时间维度
|
2
frazy 2017-04-17 12:26:36 +08:00
拿出来的时候,计费相同自己再倒叙下不就行了
|
3
frazy 2017-04-17 12:26:53 +08:00
计费=积分
|
4
hand515 2017-04-17 13:23:53 +08:00
zadd 后,往另外一个 key 插入上报时间。
排序有相同的,按另外一个 key 排 |
6
JKeita 2017-04-17 13:54:44 +08:00
存储里的值权重值根据:时间+积分,进行计算;比如时间戳+积分;实际积分值存到另一个对象里
|
8
fds 2017-04-17 14:33:54 +08:00
这种情况一般把时间加载用小数点后,不过得注意精度问题。如果是赛季那种有开始结束时间的就比较简单。
|
10
xiaowangge 2017-04-17 15:20:57 +08:00
看积分的上限是多少,如果积分上限不大的话,可以:
时间戳 乘以某个数值,例如: 写操作: timeStamp * 1000000 + 积分 查询操作,获得结果后再 除以 1000000 |
11
imherer OP @xiaowangge 嗯,这样也可以。谢谢
|
12
jiangzhuo 2017-04-17 15:24:11 +08:00
把分数乘以-1 计入 redis
|
13
jiangzhuo 2017-04-17 15:35:24 +08:00
@jiangzhuo 哎呀忘记 redis 相同 score 默认是按照字幕顺序排的了。我们用的老版本 redis 修改的
|
14
fds 2017-04-17 15:43:01 +08:00
@imherer 全写上精度可能不够,所以还是先定个范围。比如一个月为周期的话,月初的积分加上 0.9 ,月末的积分加上 0.1 ,中间按时间比例插值。当然得结合积分本身估算下精度。以十年为周期的话,精度应该也能达到天吧。
|
16
silenceeeee 2017-04-17 16:36:59 +08:00
时间戳 + 积分,这样好像有问题吧
会员 m1 的积分是 2 ,时间戳是 100 ,那么排序权值为 103 会员 m2 的积分是 1 ,时间戳是 103 ,那么排序权值为 104 这样降序排列的时候, m2 岂不是排在了 m1 之前? 或者是我哪里理解的不对? @JKeita |
17
silenceeeee 2017-04-17 16:38:19 +08:00
接上条回复: 会员 m1 的积分是 2 ,时间戳是 100 ,那么排序权值为 102 (不是 103 ) 但是不影响我列举的示例(发过的评论不能修改,有点蛋疼)
|
19
JKeita 2017-04-17 17:09:39 +08:00
@silenceeeee 艾特错了,楼上我的回复
|
20
silenceeeee 2017-04-17 17:56:29 +08:00
@JKeita 了解了。你的意思只是说把时间戳作为权重因子,但不是简单的加减,我觉得把时间戳放在小数点后就很靠谱嘛
|
21
zjuhwc 2017-04-18 08:16:58 +08:00 via iPhone
分数存成:分数-时间戳 /10 的 9 次方
晚到达的分数会小一点,要拿到准确分数向上取整就行,我们以前就这么干的 |
22
nextzeus 2018-08-16 17:25:56 +08:00
搞来搞去 还不如用数据库去二维排序最准确
|