redis实现简单的条件查询功能

今天在学习redis的时候,遇到了一个让我很纠结的问题。在sql语句中,条件查询是很简单实现的,比如:

  1. select * from books where id = 1
复制代码


这条SQL语句就能够很简单的挑选出来表books里面id等于1的书本的全部信息。但是,redis是非关系型数据库,并不支持这种通过“键值=value”查询数据的方式,那我们究竟该怎样实现类似的条件查询呢?

在登陆注册场景中,我们这样实现用户登陆时候的用户名判断。我们先假定用户信息只有用户名和密码。

注册:



  1. exports.handle_regist = function(username,password){
  2.   client.incr('uid');
  3.   client.get('uid',function(err,uid){
  4.   //建立索引集合,username--id
  5.     client.set('username:'+username,uid);
  6.     client.hmset("user:"+uid,'username',username,'password',password,function(err){
  7.       if(err){
  8.         return 0;
  9.       }
  10.       else{
  11.         return 1;
  12.       }
  13.     });
  14.   });
  15. };

复制代码


这段代码中,我们实现的是存储用户的用户名和密码的操作。

  1. client.incr('uid');
复制代码

创建 键名为uid的字符串类型键值对,每次有用户注册的数据传入时候,我们都会将uid自增1。这样,其实我们就能够知道下一位用户注册时候我们应该给他分配的uid是多少了。那为什么要分配uid呢?是为了在后面建立hash类型的键值对时候需要用到,一会再说。

  1. client.<b>get</b>(<font color="#dd1144">'uid'</font>,function(err,uid){...}
复制代码


这行代码是干嘛的呢?很明显,我们用来挑选出字符串类型的并且key=uid的value,得到value之后,实际上我们就能够为注册的用户分配唯一的ID.

  1. client.set('username:'+username,uid);
复制代码


这行代码很关键,我们在这里设置了一个“username:zhou=>1”类型的键值对索引。(‘zhou’是传过来的用户名,1是刚才得到的uid)。那么这个键值对又是干嘛的?

这个就是实现条件索引的关键了,我们为用户名和用户id建立联系,当需要挑选出用户名为zhou的用户的密码的时候,我们首先通过这个键值对索引,找到该用户的uid,再通过这个uid得到用户名密码。这样,思路就清晰了。

  1. client.hmset("user:"+uid,'username',username,'password',password,function(err){...}
复制代码


这行代码中,我们才是真正的储存用户名和密码。可以看到,我们建立了“user:1=>{username='zhou',password='123'}”形式的键值对,其中user:uid是键名,username,password是键值中的字段,用户信息是键值中字段值。这样我们就能实现用户信息的储存了。

登陆功能:




  1. exports.handle_login = function(username,password,callback){
  2.   client.get('username:'+username,function(err,uid){
  3.     if(err){
  4.       return callback(err);
  5.     }
  6.     else{
  7.       client.hget('user:'+uid,'password',function(err,pass){
  8.         if(err){
  9.           var msg = 0;
  10.           return callback(msg);
  11.         }
  12.         if(password == pass){
  13.           var msg = 1;
  14.           return callback(msg);
  15.         }
  16.         else{
  17.           var msg = 2;
  18.           return callback(msg);
  19.         }
  20.       });
  21.     }
  22.   });
  23. };
复制代码
  1. client.get('username:'+username,function(err,uid){
复制代码


我们首先通过传过来的username,在键值对“username:zhou=>uid”中寻找uid,如果没有该uid,说明没有注册,返回一个状态码;

如果找到uid,说明该用户名已经注册过,接着判断password。


  1. client.hget('user:'+uid,'password',function(err,pass){
复制代码

通过之前得到的uid查询用户信息键值对,得到password,判断用户输入的密码是否匹配,这样就能完成判断。

总结:通过以上过程不难发现,redis实现条件查询其实就是需要我们自己建立id与其他属性的联系集。比如在关系型数据库里面,建立一个汽车表car:car_id,color,price.location.当我们需要查询color等于white的所有汽车信息的时候,我们首先需要建立一个car_id和color之间的联系集,color:color_value=>uid,通过匹配得到uid再去查找汽车信息。这个方法看起来有点麻烦,但还是不知道有什么方法能替代






本文作者:geelou
本文来自云栖社区合作伙伴rediscn,了解相关信息可以关注redis.cn网站。
上一篇:Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)


下一篇:JavaScript自定义事件