Redis可以处理这个简单的查询

GyR*_*yRo 3 relational-database redis

我一直在研究与关系数据库相比的Redis功能,而不会遇到NFR问题,例如响应时间,可伸缩性等,我理解Redis的优点.

以下是Redis可以为Web应用程序处理的用例列表.
提到这一点,Redis的一个已知缺点是进行业务分析,但分析应该有多复杂,以便使Redis在比较MySQL时效率较低?

例如,如果MySQL中的以下数据结构:
表:用户 列: Id(PK),名称(VarChar),年龄(Int)
表:消息列:用户ID(FK),内容(VarChar),重要性(Int)

在我的应用程序中,我想使用以下2个查询:

 1. SELECT Content FROM Message WHERE Importance > 2;
 2. SELECT Content FROM Message,Users WHERE  User.Id=Message.UserID and
    User.Age > 30;
Run Code Online (Sandbox Code Playgroud)

我的问题:
我可以使用Redis存储上面的数据结构,并以与MySQL相同(或更高)的效率查询它吗?

Ita*_*ber 8

简短回答:是的.

答案很长:Redis是一项了不起的技术,但它不是关系型数据库.包含Redis的NoSQL构建在需要根据与其一起使用的访问模式存储数据的前提下.因此,要完成上述操作,首先必须"正确"存储数据.

要存储表的行,您似乎想要使用Hash数据结构.在Redis的术语中,以下是如何为UserID 123创建用户密钥:

HMSET user:123 id 123 name foo age 31
Run Code Online (Sandbox Code Playgroud)

注1:在构造密钥名称时使用冒号(':')仅仅是一种约定.
注意2:虽然ID已经是密钥名称的一部分,但通常在Hash中包含一个字段以便于访问.

同样,这是你将如何创建一个Message键(ID为987):

HMSET message:987 id 987 userid 123 content bar importance 3
Run Code Online (Sandbox Code Playgroud)

现在来了有趣的部分:) Redis没有FK或索引,因此您必须维护数据结构,以帮助您根据您的要求获取数据.对于您的第一个查询,最好的选择是保留一个排序集,其中成员是消息ID,分数是重要性.因此:

ZADD messages_by_importance 3 987
Run Code Online (Sandbox Code Playgroud)

获取重要性大于2的消息内容将通过两个操作完成,如此伪Pythonic代码所示:

messages = r.zrangebyscore('messages_by_importance', '(2', '+inf')
for msg in messages:
    content = r.hget('message:' + msg, 'content')
    do_something(content)
Run Code Online (Sandbox Code Playgroud)

注3:这个片段非常幼稚,可以针对更好的性能进行优化,但它应该为您提供基本的要点.

对于第二个查询,您首先需要查找超过30年的用户 - 再次,应使用相同的排序集技巧:

ZADD users_by_age 31 123
ZRANGEBYSCORE users_by_age (30 +inf
Run Code Online (Sandbox Code Playgroud)

这将为您提供符合条件的所有用户的列表,但您还需要跟踪(索引)每个用户的所有邮件.为此,请使用Set:

SADD user:123:messages 987
Run Code Online (Sandbox Code Playgroud)

要绑定所有内容,这是另一个伪代码段:

users = r.zrangebyscore('users_by_age', '(30', '+inf')
for user in users:
    messages = r.smembers('user:' + user + ':messages')
    for msg in messages:
        content = r.hget('message:' + msg, 'content')
        do_something(content)
Run Code Online (Sandbox Code Playgroud)

这应该足以让你开始,但是一旦掌握了基础知识,就要优化这些流程.根据您的需要使用流水线,Lua脚本和更智能的索引可以轻松获得...如果您需要任何进一步的帮助 - 请问:)