Redis 存儲、查詢


數據存儲

假設我們在MySQL數據庫中有這樣一張表:

mysql> desc user_info;
Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
NAME varchar(50) YES NULL
age int(11) YES NULL
email varchar(50) YES NULL
addr varchar(100) YES NULL

在redis中, 我們希望可以按照name,age,email(組合)查詢, 那么我們的redis存儲可以這樣規划:

hmset user_info.id.{id} name {name} age {age} email {email} addr {addr}

索引

sadd user_info.name.{name} {id1} {id2} {id3}
sadd user_info.age.{age} {id2} {id4} {id6}
sadd user_info.email.{email} {id1} {id3} {id9}

查詢

keys模糊查詢

//模糊查詢name中含有keywords的記錄
keys user_info.name.*keywords*

keys 支持正則匹配,但是Redis官網建議不要在prod環境使用這個命令,會降低性能。

Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don't use KEYS in your regular application code. If you're looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.

sets查詢

//按name查詢
smembers user_info.name.{name}

//按age查詢
smembers user_info.age.{age}

//按email查詢
smembers user_info.email.{email}

//按name, age組合查詢
sinter user_info.name.{name} user_info.age.{age}

注意
上面的查詢都是精確 = 查詢

scan查詢

SCAN
SCAN 迭代當前數據庫的key集合.
SSCAN
SSCAN 迭代指定Sets key集合的元素.
ZSCAN
ZSCAN 迭代指定Sorted Set key集合的元素.
HSCAN
HSCAN 迭代指定Hash key集合的field/value.

語法:
SCAN cursor [MATCH pattern] [COUNT count]

count 指定返回結果集的數量,默認為10,redis並能保證每次返回的都是count個結果

SCAN是基於游標(cursor)的,每次只返回少量的結果集,所以需要不停迭代cursor,只到cursor返回0,

127.0.0.1:6379> scan 0 count 5
1) "10"                                    // 下一次迭代cursor的起始position
2) 1) "Key_6"
   2) "Key_1"
   3) "Key_4"
   4) "Key_10"
   5) "Key_5"
   6) "Key_7"                              // 我們指定count為5,但返回了6條數據
127.0.0.1:6379> scan 10 count 5
1) "11"                                    // 下一次迭代cursor的起始position
2) 1) "Key_8"
   2) "Key_3"
   3) "Key_11"
   4) "Key_9"
   5) "Key_2"
127.0.0.1:6379> scan 11 count 5
1) "0"                                    // 0表示迭代結束
2) 1) "Key_12"

Match
這里需要注意下match執行的過程:
1, redis執行 scan x COUNT [count]
2, redis對上面的結果集進行match過濾,然后返回給client端

這就意味着,如果你使用了match過濾,則絕大多數情況下,client端每次收到的結果集數量都小於你指定的[count]數量。

// match 正則匹配, 返回含有'1'的key集合
127.0.0.1:6379> scan 0 count 5  match *1*
1) "10"
2) 1) "Key_1"
   2) "Key_10"
127.0.0.1:6379> scan 10 count 5  match *1*
1) "11"
2) 1) "Key_11"
127.0.0.1:6379> scan 11 count 5  match *1*
1) "0"
2) 1) "Key_12"
// SCAN cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> sadd age.22 id_5 id_7 id_9 id_8 id_11 id_12 id_20
(integer) 7
127.0.0.1:6379> sscan age.22 0 count 5
1) "0"
2) 1) "id_7"
   2) "id_5"
   3) "id_11"
   4) "id_8"
   5) "id_9"
   6) "id_20"
   7) "id_12"
// HSCAN key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> hmset user.id.1 name 'Troy Zhang' age 30 email 'java-koma@163.com' addr 'ChengDu, SiChuan, China' gender 'male' job 'Mobile Developer' phone '110' dept 'WEBOP CD'
OK
127.0.0.1:6379> hscan user.id.1 0
1) "0"
2)  1) "name"
    2) "Troy Zhang"
    3) "age"
    4) "30"
    5) "email"
    6) "java-koma@163.com"
    7) "addr"
    8) "ChengDu, SiChuan, China"
    9) "gender"
   10) "male"
   11) "job"
   12) "Mobile Developer"
   13) "phone"
   14) "110"
   15) "dept"
   16) "WEBOP CD"

Scan特點:
1, Scan在redis server端是無狀態的,任何時候你可以在中途中止迭代,而不需要通知redis server
2, 多個client可以同時迭代同一個cursor

Scan缺點:
1, count不能保證每次返回指定數量的結果集
2, 返回的key結果集有可能重復


總結
在prod環境下, redis建議使用scan,而不要使用 keyssmembers

Since these commands allow for incremental iteration, returning only a small number of elements per call, they can be used in production without the downside of commands like KEYS or SMEMBERS that may block the server for a long time (even several seconds) when called against big collections of keys or elements.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM