【问题标题】:Limiting the result of intersection between two sets in Redis efficiently有效限制 Redis 中两个集合之间的交集结果
【发布时间】:2020-04-28 08:45:03
【问题描述】:

我有一个考试软件系统,其中一个功能是向学生展示大量随机问题,因为以前从未向学生展示过该问题。我正在使用 redis 来实现它,所以我在我的 Redis DB 中设置了两种类型,第一种是问题库,然后每个用户都有自己的一组以前查看过的问题,这些问题在用户看到问题后会更新考试。

但是,为了提出要求,我需要从题库中为用户从未见过的每次考试找到 10 个问题。我想过使用:

SDIFFSTORE nextQuestionsToShow questionBank userQuestionsSet
SRANDMEMBER nextQuestionsToShow 10

处理结果后,我删除了生成的集合 nextQuestionsToShow。

但是,我认为这是低效的(时间和记忆方面),因为它是一个可供用户在白天随时在线的考试系统,而且题库中每个类别都有大量的问题(某些类别有超过 10 万个问题),这意味着对于每个用户来说差异是一个巨大的集合,必须存储它才能只选择 10 个随机问题。那么有没有更有效的方法来从用户之前没有回答过的问题库中随机选择 10 个问题呢?提前非常感谢。

【问题讨论】:

    标签: redis


    【解决方案1】:

    不用SET来存储userQuestionsSetquestionBank,你可以使用位图(Redis STRING)来存储这两个集合。然后你可以使用BITOP 来有效地获取两个位图之间的差异。

    更新

    首先,您需要为每个问题指定一个唯一编号。然后使用位图存储userQuestionsSetquestionBank。假设您在银行有以下问题:1: question1, 2: question2, 3: question3, 4: question4,5:问题5。并且用户已经查看了question3

    // initialize question bank: 00111110
    SETBIT question-bank 1 1
    SETBIT question-bank 2 1
    ...
    SETBIT question-bank 5 1
    
    // user has viewed question3: 00001000
    SETBIT user 3 1
    

    获取题库和用户查看的问题之间的区别:

    // XOR to get the difference: 00111110 XOR 00001000
    BITOP XOR result question-bank user
    
    // 00110110
    // questions not viewed: 1, 2, 4, 5
    GET result
    

    当你 GET 存储在 result 中的二进制字符串时,你可以扫描这个字符串,随机得到 10 个问题给用户。

    注意

    您应该小心SETBIT 可能是一项昂贵的操作,并且您最好为这些位图预先分配内存。有关详细信息,请参阅doc 的警告部分。

    【讨论】:

    • thx @for_stack .. 但你能告诉我一个 redis 命令的例子吗.. 另外,在差异之后我如何从差异中得到 10 个随机问题?
    猜你喜欢
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多