redis中两集求交结果的有效限制

bprjcwpo  于 2021-06-09  发布在  Redis
关注(0)|答案(1)|浏览(462)

我有一个考试软件系统,其中的一个特点是显示学生随机问题,从一个庞大的集合鉴于问题从来没有显示给学生之前。我使用redis来实现它,所以我在redis数据库中创建了两个类型集,第一个是问题库,然后每个用户都有自己的一组以前查看过的问题,在用户看到考试中的问题后会更新这些问题。
但是,为了满足这个要求,我需要从题库中为每个用户从未见过的考试找到10个问题。我想用:

SDIFFSTORE nextQuestionsToShow questionBank userQuestionsSet
SRANDMEMBER nextQuestionsToShow 10

在处理结果之后,我删除生成的集合nextquestionstoshow。
然而,我认为这是低效的(时间和内存方面的),因为它是一个用户在白天的任何时间在线考试系统,并且题库中每个类别有大量的问题(有些类别有超过10万个问题),这意味着,对于每个用户来说,差异是一个巨大的集合,必须存储起来,以便只选择10个随机问题。那么,有没有更有效的方法从题库中随机选择10个用户以前没有回答过的问题呢?提前多谢了。

rhfm7lfc

rhfm7lfc1#

而不是使用set来存储 userQuestionsSet 以及 questionBank ,您可以使用位图(redis string)来存储这两个集合。然后你可以用 BITOP 以有效地获得两个位图之间的差异。
更新
首先,你需要给每个问题一个唯一的数字。然后使用位图来存储 userQuestionsSet 以及 questionBank . 假设,你在银行里有以下问题:1:问题1,2:问题2,3:问题3,4:问题4,5:问题5。用户已经查看了问题3:

// 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

当您得到存储在result中的二进制字符串时,您可以扫描该字符串并为用户随机获得10个问题。
笔记
你应该小心点 SETBIT 这可能是一个昂贵的操作,您最好为这些位图预先分配内存。详见文档警告部分。

相关问题