今天在學習redis的時候,遇到了一個讓我很糾結的問題。在sql語句中,條件查詢是很簡單實作的,比如:
select * from books where id = 1
複制代碼
這條SQL語句就能夠很簡單的挑選出來表books裡面id等于1的書本的全部資訊。但是,redis是非關系型資料庫,并不支援這種通過“鍵值=value”查詢資料的方式,那我們究竟該怎樣實作類似的條件查詢呢?
在登陸注冊場景中,我們這樣實作使用者登陸時候的使用者名判斷。我們先假定使用者資訊隻有使用者名和密碼。
注冊:
exports.handle_regist = function(username,password){
client.incr('uid');
client.get('uid',function(err,uid){
//建立索引集合,username--id
client.set('username:'+username,uid);
client.hmset("user:"+uid,'username',username,'password',password,function(err){
if(err){
return 0;
}
else{
return 1;
});
});
};
這段代碼中,我們實作的是存儲使用者的使用者名和密碼的操作。
client.incr('uid');
建立 鍵名為uid的字元串類型鍵值對,每次有使用者注冊的資料傳入時候,我們都會将uid自增1。這樣,其實我們就能夠知道下一位使用者注冊時候我們應該給他配置設定的uid是多少了。那為什麼要配置設定uid呢?是為了在後面建立hash類型的鍵值對時候需要用到,一會再說。
client.<b>get</b>(<font color="#dd1144">'uid'</font>,function(err,uid){...}
這行代碼是幹嘛的呢?很明顯,我們用來挑選出字元串類型的并且key=uid的value,得到value之後,實際上我們就能夠為注冊的使用者配置設定唯一的ID.
client.set('username:'+username,uid);
這行代碼很關鍵,我們在這裡設定了一個“username:zhou=>1”類型的鍵值對索引。(‘zhou’是傳過來的使用者名,1是剛才得到的uid)。那麼這個鍵值對又是幹嘛的?
這個就是實作條件索引的關鍵了,我們為使用者名和使用者id建立聯系,當需要挑選出使用者名為zhou的使用者的密碼的時候,我們首先通過這個鍵值對索引,找到該使用者的uid,再通過這個uid得到使用者名密碼。這樣,思路就清晰了。
client.hmset("user:"+uid,'username',username,'password',password,function(err){...}
這行代碼中,我們才是真正的儲存使用者名和密碼。可以看到,我們建立了“user:1=>{username='zhou',password='123'}”形式的鍵值對,其中user:uid是鍵名,username,password是鍵值中的字段,使用者資訊是鍵值中字段值。這樣我們就能實作使用者資訊的儲存了。
登陸功能:
exports.handle_login = function(username,password,callback){
client.get('username:'+username,function(err,uid){
if(err){
return callback(err);
}
else{
client.hget('user:'+uid,'password',function(err,pass){
if(err){
var msg = 0;
return callback(msg);
}
if(password == pass){
var msg = 1;
else{
var msg = 2;
});
client.get('username:'+username,function(err,uid){
我們首先通過傳過來的username,在鍵值對“username:zhou=>uid”中尋找uid,如果沒有該uid,說明沒有注冊,傳回一個狀态碼;
如果找到uid,說明該使用者名已經注冊過,接着判斷password。
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網站。