【问题标题】:Redis interval queryRedis区间查询
【发布时间】:2016-08-28 23:50:19
【问题描述】:

我有元组 (S, T) 形式的数据,其中 S 是字符串,T 是整数。 S 和 T 都不是唯一的,但它们的组合是唯一的。我需要获取S1 == S2|T1 - T2| <= C 的所有元组。是否可以使用 Redis 高效地完成工作?

【问题讨论】:

  • 我认为,如果您澄清数据集中的元组是否是唯一的,您的问题会有所帮助。无论如何,由于 64 位的要求,我相信它很难实现(因为效率低下很难) - Redis 没有原生整数数据类型,它可以处理的最大整数大约是 53 位(分数在排序集是双精度的)。
  • 我稍微放宽了问题条件,但是还有其他一些选项(另一个数据库)更适合这项任务吗?

标签: data-structures redis processing-efficiency database nosql


【解决方案1】:

一种方法是将数据存储在列表中并使用 Lua 脚本进行检索。首先,对于 (Sn,Tn) 形式的元组,像这样插入它:

LPUSH myKey S1:T1
LPUSH myKey S2:T2
... and so on

然后,使用下面的 Lua 脚本:

local function split(div,str)
    if (div=='') then return false end
    local pos,arr = 0,{}
    for st,sp in function() return string.find(str,div,pos,true) end do
        table.insert(arr,string.sub(str,pos,st-1))
        pos = sp + 1
    end
    table.insert(arr,string.sub(str,pos))
    return arr
end

local key = KEYS[1]
local sVal = ARGV[1]
local tVal = tonumber(ARGV[2])
local cVal = tonumber(ARGV[3])
local length = redis.call("LLEN", key)

if (tonumber(length) == 0) then
    return nil
end

local data = redis.call("LRANGE", key, 0, tonumber(length))
local retval = {}

for index,val in pairs(data) do
    local parts = split(":", val)    
    if (parts[1] == sVal and math.abs(tonumber(parts[2]) - tVal) <= cVal) then
        table.insert(retval, val)
    end
end

return retval

将其保存为script.lua 并执行:

$ redis-cli "$(cat script.lua)" 1 myKey sValue tValue cValue

这将返回与S1 == S2 and |T1 - T2| &lt;= C 匹配的所有元组(Sn:Tn 形式)。

【讨论】:

  • 该解决方案的预期时间复杂度是多少?
  • 假设你的意思是时间复杂度,它会是O(n),因为它必须迭代整个列表。我认为使用 Redis 的数据结构,你不能比 O(n) 做得更好,但我很想被证明是错误的 :)
猜你喜欢
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 2022-12-15
  • 2022-01-04
  • 2012-07-02
  • 2011-03-25
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多