Sorted Set 類型
文章目錄
- Sorted Set 類型
- zadd 命令
- zrange 命令
- zcard 命令
- zcount 命令
- zrevrange 命令
- zrangebyscore 命令
- zpopmax 命令
- bzpopmax 命令
- zpopmin 命令
- bzpopmin 命令
- zrank 命令
- zscore 命令
- zrem 命令
- zremrangebyrank 命令
- zremrangebyscore 命令
- zincrby 命令
- zinterstore 命令
- zunionstore 命令
前面文章講解了 Set 類型,Set 類型有一個特點,就是集合中的元素是唯一的。而 Zset 類型(Sorted Set)不同,它是一個有序集合,集合中的每一個元素是由“兩個單元組成的”,分別是: 元素本身+對應的分數,依靠這個分數,就維護了集合中元素的有序性,什么意思呢,舉個例子:
在三國中,每一個武將都是有武力值的,我們根據武力值就可以對武將進行一個排名,如下圖:
在 zset 類型中,默認是按照**“升序”**的方式排列的,提供了一組獲取元素分數、元素范圍查詢等等功能命令,下面就來介紹一些主要并且常用的命令。
zadd 命令
使用 zadd 命令往有序集合中添加元素和分數,在不指定選項的情況下,如果元素已經存在,則更新分數,如果元素不存在,則添加元素及分數
語法:zadd key [NX | XX] [GT | LT] [CH] [INCR] score member [score member…….]
NX:只能添加新元素,如果元素已經存在,則不能修改已經存在的元素
XX:只能更新已經存在元素,如果元素不存在,不能添加新元素
CH:默認情況下,zadd 返回的是本次成功添加的元素個數,但指定這個選項之后,如果只是更新了分數,那么還會把更新分數的元素給計算上
LT:當前指定的元素必須存在,并且新的分數比當前元素的分數小,才會更新
GT:當前指定的元素必須存在,并且新的分數比當前元素的分數大,才會更新
INCR:將元素的分數加上指定的分數,此時只能指定一個元素和一個分數
score member:表示要添加的元素及分數,并且可以指定多個
操作演示:
- 不指定任何選項
zadd key score member
返回值*:成功添加的元素個數
時間復雜度:log(N),會先查找,再加入
- 指定 nx 選項
zadd key nx score member
返回值:成功添加元素的個數
時間復雜度:log(N),會先查找,再加入
使用 nx 選項添加“趙云”,因為“趙云”存在,所以并沒有對 “趙云” 這個元素進行修改
因為 “關羽” 不存在,所以,就可以成功添加 “關羽”
- 指定 xx 選項
zadd key xx score member
返回值:0,就算修改分數成功,也會返回 0
時間復雜度:log(N),會先查找,在加入
使用 xx 選項,添加 “曹操”,因為曹操這個元素已經存在,所以,就只會更新“分數”
因為 “劉備” 不存在,所以,在使用 xx 選項進行添加時,也不會成功添加
- 指定 ch 選項
zadd key ch score member
返回值:成功添加以及更新的元素個數
時間復雜度:log(N)
修改 “曹操” 的分數為77,修改成功后,返回了一個0,但是,這個返回值就不太好,我們就無法知道我們是否已經修改成功
如果加上 ch 選項,那么,就也會將成功修改的元素數量返回,如下圖:
修改曹操的分數為 95
- 指定 incr 選項
zadd key incr score member
返回值:修改之后的分數
給 “曹操” 加上 5 分
zrange 命令
查看有序集合中的元素
語法:zrange key start end [withscores]
【start end】 表示左右區間,獲取指定區間內的元素,cong 0 開始,并且支持負數
withscores 選項表示將元素的分數也顯示出來
時間復雜度:O(log(N) + M),此處 log(N) 要找start對應的位置,接下來就開始遍歷,M 表示遍歷的元素個數。
操作演示:
注意:在redis 中,對于字符,存儲的是二進制數據,在獲取的時候,獲取的也是二進制數據,并不會進行“字符集編碼”,所以,在使用 redis-cli 使用 Redis 客戶端時,需要再加一個 – raw 選項才可以顯示出來字符。
zcard 命令
獲取有序列表中元素的個數
語法:zcard key
返回值:元素個數
時間復雜度:O(1)
操作演示:
zcount 命令
獲取指定區間中元素的個數
語法:zcount key min max
min 表示左區間
max 表示右區間
并且是閉區間,是包含邊界值的,如果不想包含邊界值,可以使用 (min (max,這里的 min、max 表示下標,獲取指定下標內的元素個數
返回值:元素的個數
時間復雜度:log(N)
注意:zcount 在計算元素個數的時候,是先根據分數找到元素,在根據元素獲取到排名,兩個排名再相減,就得到了元素的個數。
操作演示:
使用開區間,不包含 98
使用開區間,不包含98,也不包含100
注意:min 和 max 是可以寫成浮點數的(zset 分數本身就是浮點數)
在浮點數中,存在兩個特殊的數值:inf(無窮大)、-inf(負無窮大),下面演示以下:
也就是獲取到所有的元素個數
zrevrange 命令
按照分數降序遍歷打印
語法:zrevrange key start end [withscores]
返回值:所有元素降序排列
時間復雜度:O(N)
操作演示:
zrangebyscore 命令
按照分數查詢元素,和上面的 zcount 類似,只不過,zcount是在下標區間內查詢,而 zrangebyscore 是在指定的分數范圍內查詢,并獲取到區間內的元素
語法:zrangebyscore key min max [withscores]
返回值:區間內的元素
時間復雜度:O(logN+M)
操作演示:
zpopmax 命令
刪除有序集合中分數最高的 count 個元素
語法:zpopmax key [count]
返回值:返回刪除的元素
時間復雜度:O(log(N)*M),M 表示刪除元素的個數
操作演示:
注意:如果存在多個元素,分數相同,并且同時為最大值,zpopmax刪除的時候,仍然刪除其中一個,因為,在有序列表中,分數相同的元素在排序時會按照字典序來排,刪除靠前的元素
bzpopmax 命令
zpopmax 的阻塞版本,如果有序集合為空,則進行阻塞,阻塞超過一定時間后,就停止阻塞等待,這里就可以把這個有序集合看成一個帶有“阻塞功能”的優先級隊列
語法:bzpopmax key [key……] timeout
這里的 timeout 單位是:秒
返回值:指定鍵中最大的元素
時間復雜度:O(logN)
操作演示:
當指定的 “鍵” 不存在時,就進行阻塞,下圖中,設置的阻塞等待時間是 600 秒
在另一個Redis 客戶端添加 key1 這個鍵,此時,正在阻塞的客戶端會直接獲取到里面的元素,返回的值包含三部分:“鍵” 、元素、分數
zpopmin 命令
刪除有序集合中最小的元素
語法:zpopmin key [count]
時間復雜度:O(logN*M)
返回值:返回刪除的元素
操作演示:
bzpopmin 命令
zpopmin 的阻塞版本,如果有序集合為空,則進行阻塞,阻塞超過一定時間后,就停止阻塞等待,這里就可以把這個有序集合看成一個帶有“阻塞功能”的優先級隊列
語法:bzpopmin key [key] timeout
可以同時監聽多個 key ,哪個 key 不為空,就返回哪個 key 中最小的元素
返回值:刪除成功的最小的元素
時間復雜度:O(logN)
這里和 bzpopmax 的用法一樣,就不在演示。
zrank 命令
查看元素在有序集合中的位置(按照升序的方式查看)
語法:zrank key member
返回值:指定元素的位置
時間復雜度:O(logN)
操作演示:
zrevrank key member
這個是按照倒序的方式查看的
zscore 命令
查詢指定元素的分數
語法:zscore key member
時間復雜度:O(1)
返回值:指定元素的分數
操作演示:
zrem 命令
刪除指定的元素
語法:zrem key member [member]、
時間復雜度:O(logN *M)
返回值:表示刪除成功的元素個數
操作演示:
zremrangebyrank 命令
刪除指定范圍內的元素
語法:zremrangebyrank key start end
時間復雜度:O(longN + M)
N 是有序集合的元素個數
M 是start - end 區間內的元素
[start,end] 這是閉區間
返回值:成功刪除元素的個數
操作演示:
zremrangebyscore 命令
通過大小分數來指定一個刪除的區間
語法:zremrangebyscore key min max
這里的 [min,max] 默認是閉區間,當然也可以通過 “(” 自定開區間
時間復雜度:O(logN+M)
返回值:成功刪除元素的個數
操作演示:
刪除[50,70] 之間的分數
zincrby 命令
給指定元素的分數加上指定的分數值
語法:zincrby key increment member
increment 表示要添加的指定分數值,也可以指定負數,這樣就變成減法了
時間復雜度:O(logN)
返回值:加上分數后的值
操作演示:
給 v6 的分數加上10
zinterstore 命令
求指定的有序列表的交集、
語法:zinterstore destination numkeys key[key….] [weigths weight……] [aggregate < sum | min | max]
destination:表示存儲交集結果的key
numskeys:表示key的數量
wieghts:給元素分配不同的權重,也就是讓元素的分數*指定的權重
agrregate 表示求交集時,交集的結果中元素的分數應該按照哪種規定描述
返回值:交集結果
操作演示:
給 key1 中添加 v1-10、v2-20、v3-30、v4-40
給 key2 中添加 v3-10、v4-20、v5-30、v6-40
求得交集的結果為
注意:這里交集結果中元素的分數默認是是交集中相同元素分數的和,但是也可以通過選項指定分數的規則
zunionstore 命令
求指定的有序列表的并集
語法:zunionstore destination numkeys key[key….] [weigths weight……] [aggregate < sum | min | max]
返回值:并集的結果
操作演示:
以上是 zset 類型中主要并且常用命令的一個簡單講解,如果想要學習其他的命令可以參考官方文檔:zset命令官方文檔跳轉鏈接