我有一个考试软件系统,其中一个功能是向学生展示一个庞大的集合中的随机问题,因为这个问题以前从未向学生展示过。我使用redis来实现它,所以我在我的Redis DB中创建了两个类型集,第一个是题库,然后每个用户都有自己的一组以前查看过的问题,这些问题在用户看到考试中的问题后会更新。
然而,为了达到这个要求,我需要从题库中为用户从未见过的每个考试找到10个问题。我想使用:
SDIFFSTORE nextQuestionsToShow questionBank userQuestionsSet
SRANDMEMBER nextQuestionsToShow 10
在处理结果之后,我删除了生成的集合nextQuestionsToShow。
然而,我认为这是低效的(时间和内存方面的),因为它是一个用户在白天随时在线考试系统,并且题库每个类别都有大量的问题(有些类别有超过10万个问题),这意味着对于每个用户来说,差异是一个巨大的集合,必须存储只选择10个随机问题。那么,有没有更有效的方法来从题库中选择10个用户以前没有回答过的随机问题呢?在此之前非常感谢。
发布于 2020-04-27 17:17:06
您可以使用位图(Redis字符串)来存储这两个集合,而不是使用SET来存储userQuestionsSet
和questionBank
。然后,您可以使用BITOP
有效地获取两个位图之间的差异。
更新
首先,你需要给每个问题一个唯一的数字。然后使用位图存储userQuestionsSet
和questionBank
。假设你在银行有以下问题: 1: question1,2: question2,3: question3,4: question4,5: question5。并且用户已经查看了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
当您获得存储在result中的二进制字符串时,您可以扫描该字符串,并随机为用户提供10个问题。
笔记
你应该小心,SETBIT
可能是一个昂贵的操作,你最好为这些位图预先分配内存。有关细节,请参阅doc的警告部分。
https://stackoverflow.com/questions/61454600
复制相似问题