是的,排序集非常快速且强大。它们似乎比SORT 操作更符合您的要求。时间复杂度经常被误解。 O(log(N)) 非常快,并且可以很好地扩展。我们将它用于一个排序集中的数千万成员。检索和插入是亚毫秒级的。
使用ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count] 获取结果。
根据您将时间戳存储为“分数”的方式,ZREVRANGEBYSCORE 可能会更好。
关于时间戳的一点说明:不需要小数部分的排序集 SCORES 应该使用 15 位或更少。所以SCORE 必须保持在 -999999999999999 到 999999999999999 的范围内。注意:存在这些限制是因为 Redis 服务器实际上在内部将分数(浮点数)存储为 redis 字符串表示形式。
因此,我推荐这种格式,将其转换为 Zulu Time: -20140313122802 以获得第二精度。您可以为 100 毫秒精度添加 1 位数字,但 如果 您不希望精度损失更多。顺便说一句,它仍然是 float64,因此在某些情况下精度损失可能没问题,但您的情况符合“完美精度”范围,所以我建议这样做。
如果您的数据在 10 年内到期,您还可以跳过前三位(CCY of CCYY),以达到 .0001 秒的精度。
我在这里建议负分,因此您可以使用更简单的ZRANGEBYSCORE 而不是REV。您可以使用 -inf 作为起始分数(负无穷大)并使用LIMIT 0 100 来获得前 100 个结果。
两个排序集members(或'keys',但这是不明确的,因为排序集本身也是一个键)可能共享一个score,没问题,结果在一个相同的score 按字母顺序排列。
希望这有帮助,TW
聊天后编辑
OP 想要从不同的键(GET/SET 或 HGET/HSET 键)收集数据(使用 ZSET)。 JOIN 可以为你做到这一点,ZRANGEBYSCORE 不能。
这样做的首选方式是一个简单的 Lua 脚本。 Lua 脚本在服务器上执行。在下面的示例中,为了简单起见,我使用EVAL,在生产中您将使用SCRIPT EXISTS、SCRIPT LOAD 和EVALSHA。大多数客户端库都内置了一些记账逻辑,因此您不必每次都上传脚本。
这是example.lua:
local r={}
local zkey=KEYS[1]
local a=redis.call('zrangebyscore', zkey, KEYS[2], KEYS[3], 'withscores', 'limit', 0, KEYS[4])
for i=1,#a,2 do
r[i]=a[i+1]
r[i+1]=redis.call('get', a[i])
end
return r
你像这样使用它(原始示例,不是为性能而编码):
redis-cli -p 14322 set activity:1 act1JSON
redis-cli -p 14322 set activity:2 act2JSON
redis-cli -p 14322 zadd feed 1 activity:1
redis-cli -p 14322 zadd feed 2 activity:2
redis-cli -p 14322 eval '$(cat example.lua)' 4 feed '-inf' '+inf' 100
结果:
1) "1"
2) "act1JSON"
3) "2"
4) "act2JSON"