【问题标题】:how to structure this SQL into a redis database如何将此 SQL 结构化为 redis 数据库
【发布时间】:2017-05-30 19:56:57
【问题描述】:

我在理解如何将此 SQL 数据库转换为 redis 数据库时遇到了一些麻烦。它是一个一对多的数据库,由关键字、响应和链接两者的关联表组成。

在我的关键字表中:

|ID---Keyword|
 1    This
 2    Cool

在我的响应表中

|ID---Response|
 1    "I agree"
 2    "wow"

在相关表中我有:

|ResponseID---KeywordID|
 1            1
 1            2
 2            2

为了尝试在 redis 中解决这个问题,我尝试使用纯字符串来创建关键字 id 到关键字的索引:

set keyword:1 This
set keyword:2 Cool

与响应相同:

set response:1 "I agree"
set response:2 "wow"

然后我用集合来加入两者:

sadd keyword:1:response 1
sadd keyword:2:response 1
sadd keyword:2:response 2

现在我目前遇到的问题是如何像在 SQL 数据库上一样轮询数据。我不确定这个问题是由于缺少添加到 redis 数据库中的信息,还是我只是缺乏经验。

基本上我想从我的软件中获取一组关键字,例如:“This”、“Cool”,然后查找它们的 ID(分别为 1 和 2)。然后从他们的 ID 中使用相关索引找到响应 ID,然后使用响应 ID 获取响应字符串。请注意,我需要首先让数据返回与最多关键字匹配的响应,因此如果给出“This”、“Cool”,则会显示响应“我同意”,尽管如果只给出关键字“Cool”“哇”和“我同意”将被检索到。

这样做的目的是,当指定更多关键字时,响应将更具体地针对这些关键字。关键字越少,它就越有可能成为一般响应。这可以在上面看到,当指定两个关键字时,只有一个响应,而当指定一个关键字时,只有两个响应。 如果可能的话,我可以将这些结果从匹配的最多的关键字排序到匹配的最少的关键字,这也会很有帮助。

关于 redis 数据库中的足够数据来实现这一点,我是否遗漏了什么?或者这是否将在客户端应用程序访问 redis 数据库中完成。

我将通过 ruby​​ 访问 redis 数据库,但如果这需要显示任何代码示例,我可以使用任何语言并将其移植过来。

【问题讨论】:

    标签: ruby database redis one-to-many


    【解决方案1】:

    一种可能的解决方案是将关键字映射到一组 redis 响应。

    keyword1 => { response1, response2 }
    keyword2 => { response1, response 3 }
    

    您从软件中获取关键字、响应 id 以及响应字符串的过程是用这种结构解决的。当您添加响应时,您会将它们添加到适当的关键字中。

    您可以使用 SCARD 获取集合中的响应数。在给定关键字列表的情况下,我个人认为没有更简单的结构可以为您提供最多匹配的关键字。

    使用集合的一个潜在有用的改进是拥有一个响应列表,这样您就可以将关键字映射存储到一个 redis 响应 id 集合。这将涉及一个额外的步骤来使用响应 id 从 redis 检索实际响应。

    keyword1 => { 0, 1 }
    keyword2 => { 0, 2 }
    responses => [ response1, response2, response3]
    

    其他想法

    您还询问了 redis 数据库中是否有足够的数据来实现这一点。鉴于上述结构,数据就在那里,但您需要决定如何/在何处计算给定关键字列表的响应计数。您可以编写一个 lua 脚本来返回将在 redis 客户端上执行的匹配最多到最少关键字的排序列表。您还可以接收 redis 集并从 ruby​​ 计算该信息。

    你应该看一下 Sets 的 redis 文档:

    Redis Sets

    如果您想查找多个关键字之间响应的重叠,则 SINTER 命令可能会派上用场。

    更新:

    我认为将所有响应放在 lua 中的一个大表中然后返回响应表及其计数是最简单的。例如:

    k1 => r1, r2, r3
    k2 => r1, r2
    k3 => r1, r3
    

    在这种情况下,我们最终会返回:

    r1: 3
    r2: 2
    r3: 2
    

    然后您可以使用该表来确定如何处理您的结果。一些lua sudo代码如下:

    local allResponses = {}
    
    -- go over the keys and add their responses to the global response table
    for keyIndex, keyword in ipairs(KEYS) do
        local responses = redis.call('smembers', keyword);
        allResponses.add(responses)
    end
    
    local counts = {}
    for responseIndex, response in ipairs(allResponses) do
        counts[response] = counts[response] + 1
    end
    
    return counts
    

    【讨论】:

    • 您好,我可以获取一个 lua 脚本示例,该脚本将返回匹配的关键字最多到最少的排序列表吗?目前,当我想尝试匹配所有给定的关键字时,SINTER 就足够了,但是如果我提供 5 个关键字,并且我只需要返回与其中任意 3 个匹配的响应,我不知道该怎么做。我的目标是,如果由于某种原因在 SINTER 期间使用的 5 个关键字未能找到响应,我想提供相同的 5,但要求它匹配任何 4,然后是 3、2、1 等,这将慢慢扩大响应的搜索词。谢谢
    • 我想我可以创建一个集合数组,这些集合在客户端旋转所有关键字的大小慢慢减小,并使用 SINTER 轮询响应并强制它,但也许有一个功能或更好的执行此操作的方法。
    • 您应该能够将每个关键字的结果放入一个大列表中,然后计算每个响应出现的次数。像计数排序这样的东西可能会很好:en.wikipedia.org/wiki/Counting_sort。今晚晚些时候我会看看我是否可以写一个 lua 脚本来演示这一点。
    猜你喜欢
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多