文章目錄
- 1 Redis命令
- Redis數據結構
- Redis 的 key 的層級結構
- 1.0 Redis通用命令
- 1.0.1 KEYS
- 1.0.2 DEL
- 1.0.3 EXISTS
- 1.0.4 EXPIRE
- 1.0.5 TTL
- 1.1 String類型
- 1.1.0 String類型的常見命令
- 1.1.1 SET 和 GET
- 1.1.2 MSET 和 MGET
- 1.1.3 INCR和INCRBY和DECY
- 1.1.4 SETNX
- 1.1.5 SETEX
- 1.2 Hash類型
- 1.2.0 Hash類型的常見命令
- 1.2.1 HSET 和 HGET
- 1.2.2 HMSET 和 HMGET
- 1.2.3 HGETALL
- 1.2.4 HKEYS 和 HVALS
- 1.2.5 HINCRBY
- 1.2.6 HSETNX
- 1.3 List類型
- 1.3.0 List類型的常見命令
- 1.3.1 LPUSH 和 RPUSH
- 1.3.2 LPOP 和 RPOP
- 1.3.3 LRANGE
- 1.3.4 BLPOP 和 BRPOP
- 1.4 Set類型
- 1.4.0 Set類型的常見命令
- 1.4.1 Set中對單個集合的操作命令
- 1.4.2 Set中對多個集合的操作命令
- 1.4.3 Set命令練習
- 1.5 SortedSet類型
- 1.5.0 SortedSet類型的常見命令
- 1.5.1 SortedSet命令練習
🙊 前言:本文章為瑞_系列專欄之《Redis》的基礎篇的Redis命令章節。由于博主是從B站黑馬程序員的《Redis》學習其相關知識,所以本系列專欄主要是針對該課程進行筆記總結和拓展,文中的部分原理及圖解等也是來源于黑馬提供的資料,特此注明。本文僅供大家交流、學習及研究使用,禁止用于商業用途,違者必究!
主機操作系統:Windows10
VMware版本:?VMware Workstation 16.2.4
Linux版本:CentOS 7 64位
遠程連接工具:MobaXterm_Personal_23.2
Redis版本:redis-6.2.6.tar.gz
Redis客戶端:resp-2022.2.0.0
相關鏈接:《瑞_VMware虛擬機安裝Linux純凈版(含卸載,圖文超詳細)》
相關鏈接:《瑞_Redis_初識Redis(含安裝教程)》
相關鏈接:《瑞_Redis_Redis客戶端》
1 Redis命令
Redis官方為了方便我們學習,將操作不同數據類型的命令也做了分組,在官網( https://redis.io/commands )可以查看到不同的命令
??Redis的命令行客戶端接受的指令是不區分大小寫的,這意味著無論你輸入的是大寫還是小寫字母,Redis都會識別并執行相同的操作。例如,SET、set和SeT都會被當作是設置鍵值對的命令。
??然而,需要注意的是,雖然Redis的指令本身不區分大小寫,但Redis的鍵(key)是嚴格區分大小寫的。如果你嘗試使用相同的鍵但是大小寫不同,Redis會將它們視為兩個完全不同的鍵。
瑞:說明:本文中出現的
#
統一代表注釋的意義,是為了圖文講解更加清晰,并非在代碼中能夠起到注釋的作用,特此說明
Redis數據結構
??Redis是典型的key-value數據庫,key一般是字符串,而value包含很多不同的數據類型:
數據類型 | 示例 | 說明 | 備注 |
---|---|---|---|
String | hello world | 基本類型 | 普通字符串 |
Hash | {“name”: “Jack”, age: 21} | 基本類型 | 字符串描述 (本質是Hash表) |
List | [A -> B -> C -> C] | 基本類型 | 有序集合,本質是鏈表 |
Set | {A, B, C} | 基本類型 | 無需集合,元素不能重復 |
SortedSet | {A: 1, B: 2, C: 3} | 基本類型 | 有序集合,元素不能重復 |
GEO | {A: (119.3, 48.6} | 特殊類型 | 地理坐標(經緯度) |
BitMap | 0110110101110101011 | 特殊類型 | 特殊統計 |
HyperLog | 0110110101110101011 | 特殊類型 | 特殊統計 |
??不同類型的命令稱為一個group,我們也可以通過help命令來查看各種不同group的命令:
Redis 的 key 的層級結構
??Redis沒有類似MySQL中的Table的概念,我們該如何區分不同類型的key呢?
??例如,需要存儲用戶、商品信息到redis,有一個用戶id是1,有一個商品id恰好也是1,此時如果使用id作為key,那就會沖突了,該怎么辦?
??我們可以通過給key添加前綴加以區分,不過這個前綴不是隨便加的,有一定的規范:
??Redis的key允許有多個單詞形成層級結構,多個單詞之間用':'
隔開,如下示例??
??這個格式并非固定,也可以根據自己的需求來刪除或添加詞條。
??例如我們的項目名稱叫 heima,有user和product兩種不同類型的數據,我們可以這樣定義key:
- user相關的key:heima:user:1
- product相關的key:heima:product:1
??如果Value是一個Java對象,例如一個User對象,則可以將對象序列化為JSON字符串后存儲:
KEY | VALUE |
---|---|
heima:user:1 | {“id”:1, “name”: “Jack”, “age”: 21} |
heima:product:1 | {“id”:1, “name”: “小米11”, “price”: 4999} |
??一旦我們向redis采用這樣的方式存儲,那么在可視化界面中,redis會以層級結構來進行存儲,形成類似于這樣的結構,更加方便Redis獲取數據
??如執行以下命令
127.0.0.1:6379> set heima:user:1 '{"id":1, "name":"Jack", "age": 21}'
127.0.0.1:6379> set heima:user:2 '{"id":2, "name":"Rose", "age": 18}'
127.0.0.1:6379> set heima:product:1 '{"id":1, "name":"小米11", "price": 4999}'
127.0.0.1:6379> set heima:product:2 '{"id":2, "name":"榮耀6", "price": 2999}'
??使用Redis客戶端圖形界面查看,發現自動分出了層級關系,這樣就非常清晰
瑞:Redis客戶端相關知識推薦:《瑞_Redis_Redis客戶端》
1.0 Redis通用命令
查看通用命令:
help @generic
??通用指令是部分數據類型的,都可以使用的指令,常見的有:
- KEYS:查看符合模板的所有key,不建議在生產環境設備上使用
- DEL:刪除一個指定的key
- EXISTS:判斷key是否存在
- EXPIRE:給一個key設置有效期,有效期到期時該key會被自動刪除
- TTL:查看一個KEY的剩余有效期
??通過help [command] 可以查看一個命令的具體用法,例如:
# 查看keys命令的幫助信息:
127.0.0.1:6379> help keysKEYS pattern
summary: Find all keys matching the given pattern
since: 1.0.0
group: generic
1.0.1 KEYS
- KEYS:查看符合模板的所有key,不建議在生產環境設備上使用
瑞:不要在主節點上使用該命令,容易造成阻塞。尤其是數據量大的時候,千萬不要用
KEYS *
,*使用了模糊匹配查詢的機制,效率很低,而Redis執行命令是單線程的,最終導致Redis服務阻塞
語法:
keys pattern
??用法如下
# 數據準備
## 創建一個名為"name"的鍵,并將其值設置為"ray"
set name ray
## 創建一個名為"age"的鍵,并將其值設置為21
set age 21# keys 命令
## 這個命令將返回數據庫中所有鍵的列表
keys *
## 這個命令將返回所有以"a"開頭的鍵的列表
keys a*
## 這個命令將返回名為"name"的鍵的列表
keys name
1.0.2 DEL
- DEL:刪除一個指定的key
語法:
del key [key ...]
??用法如下
# 刪除名為"name"的鍵(單個)
127.0.0.1:6379> del name
(integer) 1 #成功刪除1個
127.0.0.1:6379> keys *
1) "age"
# 一次性批量設置多個鍵值對,分別是k1-v1、k2-v2和k3-v3
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> keys *
1) "k3"
2) "age"
3) "k2"
4) "k1"
# 刪除名為"k1"、"k2"、"k3"和"k4"的四個鍵
127.0.0.1:6379> del k1 k2 k3 k4
# 由于沒有k4,所以返回的刪除個數,3個建被刪除
(integer) 3 #此處返回的是成功刪除的key,由于redis中只有k1,k2,k3 所以只成功刪除3個,最終返回
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379>
1.0.3 EXISTS
- EXISTS:判斷key是否存在
語法:
exists key [key ...]
??用法如下
# 判斷鍵"age"是否存在
127.0.0.1:6379> exists age
# 存在,返回1
(integer) 1
# 判斷鍵"name"是否存在
127.0.0.1:6379> exists name
# 不存在,返回0
(integer) 0
127.0.0.1:6379>
1.0.4 EXPIRE
- EXPIRE:給一個key設置有效期,有效期到期時該key會被自動刪除
語法:
expire key seconds
瑞:在實際開發中EXPIRE命令常和TTL命令一起使用。常見業務需求:如短信驗證碼的有效期5分鐘。由于內存非常寶貴,所以對于一些數據,我們應當給他一些過期時間,當過期時間到了之后,就會自動被刪除
??用法如下
# 設置鍵"age"的有效期為20秒
127.0.0.1:6379> expire age 20
# 設置成功返回1,不成功返回0
(integer) 1
1.0.5 TTL
- TTL:查看一個KEY的剩余有效期
語法:
ttl key
瑞:TTL(Time To Leave)剩余生存時間
??用法如下
# 設置鍵"age"的有效期為20秒
127.0.0.1:6379> expire age 20
# 查看鍵"age"的剩余有效期
127.0.0.1:6379> ttl age
# 大于0則返回當前該鍵的剩余有效期
(integer) 16
127.0.0.1:6379> ttl age
# 返回-2則表示該鍵已經被移除
(integer) -2
瑞:在Redis中存放數據的時候最好都設置一個有效期
1?? 如果是expire
命令設置鍵的有效期,使用ttl
命令查看該鍵的時候,如果存在則返回該鍵的剩余有效期,如果不存在則返回-2(-2代表該鍵被移除)。
2?? 如果只是set
命令設置的鍵并且沒有使用expire
命令設置鍵的有效期,使用ttl
命令查看該鍵的時候則返回-1(-1代表改鍵永久有效)。
1.1 String類型
??String類型,也就是字符串類型,是Redis中最簡單的存儲類型。其value是字符串,不過根據字符串的格式不同,又可以分為3類:
??1?? string:普通字符串
??2?? int:整數類型,可以做自增/自減操作
??3?? float:浮點類型,可以做自增/自減操作
KEY | VALUE |
---|---|
msg | hello world |
num | 10 |
score | 92.5 |
不管是哪種格式,底層都是字節數組形式存儲,只不過是編碼方式不同。字符串類型的最大空間不能超過512m
1.1.0 String類型的常見命令
- SET:添加或者修改已經存在的一個String類型的鍵值對
- GET:根據key獲取String類型的value
- MSET:批量添加多個String類型的鍵值對
- MGET:根據多個key獲取多個String類型的value
- INCR:讓一個整型的key自增1
- INCRBY:讓一個整型的key自增并指定步長,例如:incrby num 2 讓num值自增2
- INCRBYFLOAT:讓一個浮點類型的數字自增并指定步長
- SETNX:添加一個String類型的鍵值對,前提是這個key不存在,否則不執行
- SETEX:添加一個String類型的鍵值對,并且指定有效期
瑞:以上命令除了INCRBYFLOAT 都是常用命令
1.1.1 SET 和 GET
- SET:添加或者修改已經存在的一個String類型的鍵值對(如果key不存在則是新增,如果存在則是修改)
語法:
set key value [EX seconds|PX milliseconds|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL]
- GET:根據key獲取String類型的value
語法:
get key
??用法如下
127.0.0.1:6379> keys *
(empty array) # 此時無數據
127.0.0.1:6379> set name Rose # 原來不存在"name"鍵,所以為新增操作
OK
127.0.0.1:6379> get name
"Rose" # 驗證結果
127.0.0.1:6379> set name Jack # 已存在"name",所以為修改,將"Rose"改為"Jack"
OK
127.0.0.1:6379> get name
"Jack" # 驗證結果
127.0.0.1:6379>
1.1.2 MSET 和 MGET
- MSET:批量添加多個String類型的鍵值對
語法:
mset key value [key value ...]
- MGET:根據多個key獲取多個String類型的value
語法:
mget key [key ...]
??用法如下
# 一次性批量設置多個鍵值對,分別是k1-v1、k2-v2和k3-v3
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> MGET name age k1 k2 k3
1) "Jack"
2) (nil) # 不存在key-age
3) "v1"
4) "v2"
5) "v3"
1.1.3 INCR和INCRBY和DECY
- INCR:讓一個整型的key自增1
語法:
incr key
- INCRBY:讓一個整型的key自增并指定步長,例如:incrby num 2 讓num值自增2
語法:
incrby key increment
- INCRBYFLOAT:讓一個浮點類型的數字自增并指定步長
語法:
incrbyfloat key increment
瑞:浮點型自增必須要指定步長。由于INCRBY 能夠實現減操作,所以一般 DECR和DECRBY 命令是用 INCRBY 命令代替。
??用法如下
# 準備一個整形的key
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> get age
"18"
127.0.0.1:6379> incr age # 執行自增
(integer) 19
127.0.0.1:6379> incr age
(integer) 20
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incrby age 2 # 執行自增,指定步長為2
(integer) 23
127.0.0.1:6379> incrby age -1 # 執行自增,指定步長為-1,相當于減
(integer) 22
127.0.0.1:6379> set score 10.0 # 準備一個浮點型的key
OK
127.0.0.1:6379> incrbyfloat score 0.6 # 讓浮點型自增,步長為0.5
"10.6"
127.0.0.1:6379> incrbyfloat score 0.6
"11.2"
127.0.0.1:6379>
1.1.4 SETNX
- SETNX:添加一個String類型的鍵值對,前提是這個key不存在,否則不執行
語法:
setnx key value
瑞:真正的新增。
setnx
其實是組合命令,setnx key value
相當于set key value nx
??用法如下
# 官方介紹
127.0.0.1:6379> help SETNXSETNX key valuesummary: Set the value of a key, only if the key does not existsince: 1.0.0group: string# 當前數據
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
4) "name"
5) "age"
6) "score"
127.0.0.1:6379> setnx name ray # 嘗試添加已存在的key-name
(integer) 0 # 返回0,表示添加失敗
127.0.0.1:6379> get name
"Jack" # key-name仍然存儲原來的value-Jack
127.0.0.1:6379> setnx name2 ray # 嘗試添加不存在的key-name2
(integer) 1 # 添加成功
127.0.0.1:6379> get name2
"ray"
127.0.0.1:6379> set name wangwu nx # setnx相當于set key value nx
(nil) # 添加失敗
127.0.0.1:6379> get name
"Jack"
127.0.0.1:6379> set name3 wangwu nx # setnx相當于set key value nx
OK # 添加成功
127.0.0.1:6379> get name3
"wangwu"
127.0.0.1:6379>
1.1.5 SETEX
- SETEX:添加或修改一個String類型的鍵值對,并且指定有效期
語法:
setex key seconds value
瑞:
SETEX
是組合命令,相當于set key value
加expire key seconds
命令的組合執行結果。
即setex key seconds value
相當于set key value ex seconds
??用法如下
# 官方介紹
127.0.0.1:6379> help setexSETEX key seconds valuesummary: Set the value and expiration of a keysince: 2.0.0group: string
# 此時存在key-name存儲value-Jack
127.0.0.1:6379> keys *
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name"
6) "name3"
7) "score"
127.0.0.1:6379> setex name 10 ray # 添加或修改(此處為修改)一個String類型的鍵值對name-ray,并且指定有效期10秒
OK
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> get name
"ray" # 確定name的value被修改為ray
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) -2 # 此時過期
127.0.0.1:6379> keys * # 不存在name
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name3"
6) "score"
# 以下驗證`setex key seconds value`相當于`set key value ex seconds`,相同的操作
127.0.0.1:6379> set name Jack ex 10
OK
127.0.0.1:6379> ttl name
(integer) 8
127.0.0.1:6379> get name
"Jack" # 此時是新增
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> keys *
1) "name2"
2) "k3"
3) "k2"
4) "k1"
5) "name3"
6) "score"
127.0.0.1:6379>
1.2 Hash類型
??Hash類型,也叫散列,其value是一個無序字典,類似于Java中的HashMap結構(類似Map<key,Map<key,value>>但還是有差異的)。
??String結構是將對象序列化為JSON字符串后存儲,當需要修改對象某個字段時很不方便:
KEY | VALUE |
---|---|
heima:user:1 | {name:“Jack”, age:21} |
heima:user:2 | {name:“Rose”, age:18} |
??Hash結構可以將對象中的每個字段獨立存儲,可以針對單個字段做CRUD:
瑞:Hash結構相對String結構更加靈活,可以將value拆分為多個獨立字段進行存儲。
1.2.0 Hash類型的常見命令
- HSET key field value:添加或者修改hash類型key的field的值
- HGET key field:獲取一個hash類型key的field的值
- HMSET:批量添加多個hash類型key的field的值
- HMGET:批量獲取多個hash類型key的field的值
- HGETALL:獲取一個hash類型的key中的所有的field和value
- HKEYS:獲取一個hash類型的key中的所有的field
- HVALS:獲取一個hash類型的key中的所有的value
- HINCRBY:讓一個hash類型key的字段值自增并指定步長
- HSETNX:添加一個hash類型的key的field值,前提是這個field不存在,否則不執行
瑞:哈希結構是實際開發中常用的命令。Hash類型命令可以與String類型命令捆綁記憶,String類型命令前加上H就是Hash類型命令,語法上添加field指明是哪個字段即可
1.2.1 HSET 和 HGET
- HSET key field value:添加或者修改hash類型key的field的值
語法:
hset key field value [field value ...]
- HGET key field:獲取一個hash類型key的field的值
語法:
hget key field
??用法如下
127.0.0.1:6379> hset heima:user:3 name Lucy
(integer) 1
127.0.0.1:6379> hset heima:user:3 age 29
(integer) 1
127.0.0.1:6379> hget heima:user:3 name
"Lucy"
127.0.0.1:6379> hget heima:user:3 age
"29"
127.0.0.1:6379> hset heima:user:3 age 21
(integer) 0 # 返回0表示修改
127.0.0.1:6379> hget heima:user:3 age
"21"
127.0.0.1:6379>
??使用客戶端查看
1.2.2 HMSET 和 HMGET
- HMSET:批量添加多個hash類型key的field的值
語法:
hmset key field value [field value...]
- HMGET:批量獲取多個hash類型key的field的值
語法:
hmget key field [field ...]
??用法如下
127.0.0.1:6379> hmset heima:user:4 name HanMeiMei
OK
127.0.0.1:6379> hmset heima:user:4 name LiLei age 20 sex man
OK
127.0.0.1:6379> hmget heima:user:4 name age sex
1) "LiLei"
2) "20"
3) "man"
127.0.0.1:6379>
1.2.3 HGETALL
- HGETALL:獲取一個hash類型的key中的所有的field和value
語法:
hgetall key
??用法如下
127.0.0.1:6379> hgetall heima:user:4
1) "name"
2) "LiLei"
3) "age"
4) "20"
5) "sex"
6) "man"
1.2.4 HKEYS 和 HVALS
- HKEYS:獲取一個hash類型的key中的所有的field
語法:
hkeys key
- HVALS:獲取一個hash類型的key中的所有的value
語法:
hvals key
瑞:
HKEYS 可以理解成 Java 中 HashMap 的 keySet()
HVALS 可以理解成 Java 中 HashMap 的 entrySet()
??用法如下
127.0.0.1:6379> hkeys heima:user:4
1) "name"
2) "age"
3) "sex"
127.0.0.1:6379> hvals heima:user:4
1) "LiLei"
2) "20"
3) "man"
1.2.5 HINCRBY
- HINCRBY:讓一個hash類型key的字段值自增并指定步長
瑞:語法:
hincrby key field increment
,支持減操作
??用法如下
127.0.0.1:6379> hincrby heima:user:4 age 2
(integer) 22
127.0.0.1:6379> hvals heima:user:4
1) "LiLei"
2) "22"
3) "man"
127.0.0.1:6379> hincrby heima:user:4 age 2
(integer) 24
127.0.0.1:6379>
127.0.0.1:6379> hincrby heima:user:4 age -10
(integer) 14
127.0.0.1:6379>
1.2.6 HSETNX
- HSETNX:添加一個hash類型的key的field值,前提是這個field不存在,否則不執行
語法:
hsetnx key field value
瑞:Hash類型的真正新增,和String類型不同,新增的是field-value
??用法如下
127.0.0.1:6379> hsetnx heima:user:4 sex woman
(integer) 0
127.0.0.1:6379> hsetnx heima:user:3 sex woman
(integer) 1
127.0.0.1:6379> hgetall heima:user:3
1) "name"
2) "Lucy"
3) "age"
4) "21"
5) "sex"
6) "woman"
127.0.0.1:6379>
1.3 List類型
??Redis 中的 List 類型與 Java 中的 LinkedList 類似,可以看做是一個雙向鏈表結構(實際結構會更復雜)。既可以支持正向檢索和也可以支持反向檢索。
??特征也與LinkedList類似:
- 有序
- 元素可以重復
- 插入和刪除快
- 查詢速度一般
??常用來存儲一個有序數據,例如:朋友圈點贊列表,評論列表等。
1.3.0 List類型的常見命令
- LPUSH key element … :向列表左側插入一個或多個元素
- LPOP key:移除并返回列表左側的第一個元素,沒有則返回nil
- RPUSH key element …:向列表右側插入一個或多個元素
- RPOP key:移除并返回列表右側的第一個元素
- LRANGE key star end:返回一段角標范圍內的所有元素
- BLPOP和BRPOP:與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil
瑞:將鏈表看作隊列后:L可以理解為左側,即隊首。R可以理解為右側,即隊尾。
1.3.1 LPUSH 和 RPUSH
- LPUSH key element … :向列表左側插入一個或多個元素
語法:
lpush key element [element ...]
??用法如下
127.0.0.1:6379> lpush users 1 2 3
(integer) 3
??注意:是 3 2 1,而不是按照命令順序? 1 2 3 ?
先左推1,此時:1
然后左推2,所以2在1的左邊,此時:2 <-> 1
然后左推3,所以3在2的左邊,此時:3 <-> 2 <-> 1
- RPUSH key element …:向列表右側插入一個或多個元素
語法:
rpush key element [element ...]
??用法如下
27.0.0.1:6379> rpush users 4 5 6
(integer) 6
??右側和正常邏輯相同,所以最終結果:3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
1.3.2 LPOP 和 RPOP
- LPOP key:移除并返回列表左側的第一個元素,沒有則返回nil
語法:
lpop key [count]
- RPOP key:移除并返回列表右側的第一個元素
語法:
rpop key [count]
瑞:如同出隊類似,元素會從列表中移除
??用法如下
# 開始3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
# 移除并返回列表左側的第一個元素3,此時2 <-> 1 <-> 4 <-> 5 <-> 6
127.0.0.1:6379> lpop users 1
1) "3"
# 移除并返回列表右側的第一個元素6,此時2 <-> 1 <-> 4 <-> 5
127.0.0.1:6379> rpop users 1
1) "6"
1.3.3 LRANGE
- LRANGE key star end:返回一段角標范圍內的所有元素
語法:
lrange key start stop
??用法如下
# 開始3 <-> 2 <-> 1 <-> 4 <-> 5 <-> 6
# 移除并返回列表左側的第一個元素3,此時2 <-> 1 <-> 4 <-> 5 <-> 6
127.0.0.1:6379> lpop users 1
1) "3"
# 移除并返回列表右側的第一個元素6,此時2 <-> 1 <-> 4 <-> 5
127.0.0.1:6379> rpop users 1
1) "6"
127.0.0.1:6379> lrange users 1 2 # 返回下標為1的"1"到下標為2的"4"
1) "1"
2) "4"
1.3.4 BLPOP 和 BRPOP
- BLPOP和BRPOP:與LPOP和RPOP類似,只不過在沒有元素時等待指定時間,而不是直接返回nil
語法:
blpop key [key ...] timeout
語法:brpop key [key ...] timeout
瑞:BLPOP、BRPOP跟LPOP、RPOP主要區別在于前者是阻塞式獲取
??用法如下
# 控制臺1中
# 下面一條命令不符合blpop語法,因為等待時間必須指定
127.0.0.1:6379> blpop users2
(error) ERR wrong number of arguments for 'blpop' command
# 阻塞等待了近100秒后,仍然沒有user2的數據,返回(nil)
127.0.0.1:6379> blpop users2 100
(nil)
(100.11s)
# 阻塞等待了近17.26秒后,使用控制臺2對user2出入數據"Jack",此時返回列表
127.0.0.1:6379> blpop users2 100
1) "users2"
2) "Jack"
(17.26s)
127.0.0.1:6379>
# 新建控制臺2,進入Redis命令行客戶端,警告是指使用-a指令導致密碼未加密,所以警告此操作不安全,學習時可直接忽略
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# 在控制臺1執行blpop命令時插入數據
127.0.0.1:6379> lpush users2 Jack
(integer) 1
127.0.0.1:6379>
1.4 Set類型
??Redis的Set結構與Java中的HashSet類似,可以看做是一個value為null的HashMap。因為也是一個hash表,因此具備與HashSet類似的特征:
- 無序
- 元素不可重復
- 查找快
- 支持交集、并集、差集等功能
1.4.0 Set類型的常見命令
- SADD key member … :向set中添加一個或多個元素
- SREM key member … : 移除set中的指定元素
- SCARD key: 返回set中元素的個數
- SISMEMBER key member:判斷一個元素是否存在于set中
- SMEMBERS:獲取set中的所有元素
- SINTER key1 key2 … :求key1與key2的交集
- SDIFF key1 key2 … :求key1與key2的差集
- SUNION key1 key2 …:求key1和key2的并集
1.4.1 Set中對單個集合的操作命令
- SADD key member … :向set中添加一個或多個元素
語法:
sadd key member [member ...]
- SREM key member … : 移除set中的指定元素
語法:
srem key member [member ...]
- SCARD key: 返回set中元素的個數
語法:
scard key
- SISMEMBER key member:判斷一個元素是否存在于set中
語法:
sismember key member
- SMEMBERS:獲取set中的所有元素
語法:
smembers key
??用法如下
# 向set-s1中添加元素a b c
127.0.0.1:6379> sadd s1 a b c
(integer) 3
# 獲取set-s1中所有元素
127.0.0.1:6379> SMEMBERS s1
1) "c"
2) "a"
3) "b"
# 移除set-s1中的指定元素a
127.0.0.1:6379> srem s1 a
(integer) 1
# 判斷a是否在set-s1中
127.0.0.1:6379> sismember s1 a
(integer) 0
# 判斷b是否在set-s1中
127.0.0.1:6379> sismember s1 b
(integer) 1
# 返回set-s1中元素的個數
127.0.0.1:6379> scard s1
(integer) 2
127.0.0.1:6379>
1.4.2 Set中對多個集合的操作命令
- SINTER key1 key2 … :求key1與key2的交集
語法:
sinter key [key ...]
- SDIFF key1 key2 … :求key1與key2的差集
語法:
sdiff key [key ...]
- SUNION key1 key2 …:求key1和key2的并集
語法:
sunion key [key ...]
??假設集合s1有元素A、B、C,集合s2有元素B、C、D
??則s1和s2的交集、差集、并集如下
1.4.3 Set命令練習
將下列數據用Redis的Set集合來存儲:
- 張三的好友有:李四.王五.趙六
SADD zs lisi wangwu zhaoliu
- 李四的好友有:王五.麻子.二狗
SADD ls wangwu mazi ergou
利用Set的命令實現下列功能:
- 計算張三的好友有幾人
SCARD zs
- 計算張三和李四有哪些共同好友
SINTER zs ls
- 查詢哪些人是張三的好友卻不是李四的好友
SDIFF zs ls
- 查詢張三和李四的好友總共有哪些人
SUNION zs ls
- 判斷李四是否是張三的好友
SISMEMBER zs lisi
- 判斷張三是否是李四的好友
SISMEMBER ls zhangsan
- 將李四從張三的好友列表中移除
SREM zs lisi
1.5 SortedSet類型
??Redis 的 SortedSet 是一個可排序的 set 集合,與 Java 中的 TreeSet 有些類似,但底層數據結構卻差別很大。SortedSet 中的每一個元素都帶有一個 score 屬性,可以基于 score 屬性對元素排序,底層的實現是一個跳表(SkipList)加 hash 表。
??SortedSet具備下列特性:
- 可排序
- 元素不重復
- 查詢速度快
??因為SortedSet的可排序特性,經常被用來實現排行榜這樣的功能。
1.5.0 SortedSet類型的常見命令
- ZADD key score member:添加一個或多個元素到sorted set ,如果已經存在則更新其score值
- ZREM key member:刪除sorted set中的一個指定元素
- ZSCORE key member : 獲取sorted set中的指定元素的score值
- ZRANK key member:獲取sorted set 中的指定元素的排名
- ZCARD key:獲取sorted set中的元素個數
- ZCOUNT key min max:統計score值在給定范圍內的所有元素的個數
- ZINCRBY key increment member:讓sorted set中的指定元素自增,步長為指定的increment值
- ZRANGE key min max:按照score排序后,獲取指定排名范圍內的元素
- ZRANGEBYSCORE key min max:按照score排序后,獲取指定score范圍內的元素
- ZDIFF.ZINTER.ZUNION:求差集.交集.并集
??注意:所有的排名默認都是升序,如果要降序則在命令的 Z 后面添加 REV 即可,例如:
- 升序獲取sorted set 中的指定元素的排名:
ZRANK key member
- 降序獲取sorted set 中的指定元素的排名:
ZREVRANK key memeber
1.5.1 SortedSet命令練習
??將班級的下列學生得分存入Redis的SortedSet中:
??Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
??zadd stus 85 Jack 89 Lucy 82 Rose 95 Tom 78 Jerry 92 Amy 76 Miles
??并實現下列功能:
- 刪除Tom同學
zrem stus Tom
- 獲取Amy同學的分數
zscore stus Amy
- 獲取Rose同學的排名
zrank stus Rose
- 查詢80分以下有幾個學生
zcount stus 0 80
- 給Amy同學加2分
zincrby stus 2 Amy
- 查出成績后3名的同學
zrange stus 0 2
- 查出成績前3名的同學
zrevrange stus 0 2
- 查出成績80分以下的所有同學
zrangebyscore stus 0 80
??如果覺得這篇文章對您有所幫助的話,請動動小手點波關注💗,你的點贊👍收藏??轉發🔗評論📝都是對博主最好的支持~