006.Redis基本數據結構五:有序集合(待完善)
- 2020 年 3 月 26 日
- 筆記
1. 有序集合簡介
有序集合保留了集合中不能有重複成員的特性,同時又對集合中的元素進行排序。列表是使用索引下標作為 排序的依據,有序集合則是給每個元素設置一個分數(score)作為排序的依據。

2. 常用命令
# (1) 添加元素:ZADD key [NX|XX] [CH] [INCR] score value # NX:value必須不存在才可以添加成功 # XX:value必須存在才可以添加成功,用於更新 # CH:返回score或者value發生變化的個數 # INCR:score # 返回添加成功的個數 beh07:6379> ZADD students 100 tom (integer) 1 beh07:6379> ZADD students 98 tony (integer) 1 beh07:6379> ZADD students CH 77 bob 88 tom (integer) 2 # 在原來score的基礎上+87,返回增加之後的分值 beh07:6379> ZADD students INCR 87 jack "174" # (2) 統計元素個數 beh07:6379> ZCARD students (integer) 4 # (3) 獲取元素分值 beh07:6379> ZSCORE students tom "88" # (4) 計算排名 # 獲取[m,n]位排序後的元素,[0,-1]代表獲取全部元素,默認是使用score升序排序 beh07:6379> ZRANGE students 0 -1 1) "bob" 2) "tom" 3) "tony" 4) "jack" # 獲取[m,n]位排序後的元素,[0,-1]代表獲取全部元素,降序排序,withscores參數可以返回分數 beh07:6379> ZREVRANGE students 0 2 WITHSCORES 1) "jack" 2) "174" 3) "tony" 4) "98" 5) "tom" 6) "88" # 獲取指定value的排名(升序,從0開始) beh07:6379> ZRANK students tom (integer) 1 # 獲取指定vaue的排名(降序,從0開始) beh07:6379> ZREVRANK students tom (integer) 2 # (5) 刪除元素 beh07:6379> ZREM students jack (integer) 1 # (6) 增加分數 beh07:6379> ZSCORE students tom "88" beh07:6379> ZINCRBY students 12 tom "100" # (7) 返回指定排名範圍的成員 # 返回倒數前3名 beh07:6379> zrange students 0 2 withscores 1) "Eirene" 2) "92" 3) "Habiba" 4) "93" 5) "Isoke" 6) "94" # 返回前3名 beh07:6379> zrevrange students 0 2 withscores 1) "tom" 2) "100" 3) "Miki" 4) "99" 5) "tony" 6) "98" # (8) 返回指定分數範圍的成員 # zrangebyscore key min max [withscores] [limit offset count] # zrevrangebyscore key min max [withscores] [limit offset count] # zrangebyscore升序,zrevrangebyscore降序 # 指定的範圍min和max都會包括到輸出範圍,[min, max] # [limit offset count]用於限制輸出的起始位置和個數 beh07:6379> zrangebyscore students 95 99 withscores 1) "Jayne" 2) "95" 3) "Joy" 4) "96" 5) "Kirima" 6) "97" 7) "Laura" 8) "98" 9) "tony" 10) "98" 11) "Miki" 12) "99" # +inf:正無窮,-inf:負無窮 beh07:6379> zrangebyscore students 95 +inf withscores 1) "Jayne" 2) "95" 3) "Joy" 4) "96" 5) "Kirima" 6) "97" 7) "Laura" 8) "98" 9) "tony" 10) "98" 11) "Miki" 12) "99" 13) "tom" 14) "100" beh07:6379> zrangebyscore students -inf 90 withscores 1) "bob" 2) "77" 3) "Allen" 4) "90" # 從第4名開始輸出2個結果(第一名索引為0) beh07:6379> zrangebyscore students -inf +inf withscores limit 3 2 1) "Eirene" 2) "92" 3) "Habiba" 4) "93" # 支援開區間,'('代表開區間,默認是閉區間 beh07:6379> zrangebyscore students (90 93 withscores 1) "Danica" 2) "91" 3) "Eirene" 4) "92" 5) "Habiba" 6) "93" beh07:6379> zrangebyscore students 90 (93 withscores 1) "Allen" 2) "90" 3) "Danica" 4) "91" 5) "Eirene" 6) "92" beh07:6379> zrangebyscore students (90 (93 withscores 1) "Danica" 2) "91" 3) "Eirene" 4) "92" # (9) 返回指定分數範圍內的成員個數 beh07:6379> zcount students 90 100 (integer) 12 # (10) 刪除指定排名內的成員 # 升序排序,刪除前3名 beh07:6379> zremrangebyrank students 0 2 (integer) 3 # (11) 刪除指定分數範圍內的成員 beh07:6379> zremrangebyscore students 95 99 (integer) 6 # (12) 刪除指定值的元素 beh07:6379> zrem students tom (integer) 1
3. 集合間操作
準備測試數據:

beh07:6379> zadd user1 67 Allen 88 Mike 98 Candy 97 Ella 99 Hebe 56 Wawa (integer) 6 beh07:6379> zadd user2 73 Bob 82 Mike 43 Hebe 77 Wawa (integer) 4
# (1) 交集 # 對集合user1和user2做交集,結果保存到user_inter1集合中 # 數字2的意思做交集的集合的個數,zinterstore user_inter_tmp n user1 user2 ... usern beh07:6379> zinterstore user_inter1 2 user1 user2 (integer) 3 # 可以看到對於相同的value的分數做了加法 beh07:6379> zrange user_inter1 0 -1 withscores 1) "Wawa" 2) "133" 3) "Hebe" 4) "142" 5) "Mike" 6) "170" # 指定權重,默認為1 beh07:6379> zinterstore user_inter2 2 user1 user2 WEIGHTS 1 0.5 AGGREGATE max (integer) 3 # 最終分數的計算過程 score = max(user1.value.score * 1, user2.value.score * 0.5) # 支援的聚合操作有max/min/sum,默認使用sum beh07:6379> zrange user_inter2 0 -1 withscores 1) "Wawa" 2) "56" 3) "Mike" 4) "88" 5) "Hebe" 6) "99" # (2) 並集 # zunionstore的參數用法與zinterstore相同 beh07:6379> zunionstore user_union1 2 user1 user2 (integer) 7 beh07:6379> zrange user_union1 0 -1 withscores 1) "Allen" 2) "67" 3) "Bob" 4) "73" 5) "Ella" 6) "97" 7) "Candy" 8) "98" 9) "Wawa" 10) "133" 11) "Hebe" 12) "142" 13) "Mike" 14) "170" beh07:6379> zunionstore user_union2 2 user1 user2 WEIGHTS 1 0.5 AGGREGATE MIN (integer) 7 beh07:6379> zrange user_union2 0 -1 withscores 1) "Hebe" 2) "21.5" 3) "Bob" 4) "36.5" 5) "Wawa" 6) "38.5" 7) "Mike" 8) "41" 9) "Allen" 10) "67" 11) "Ella" 12) "97" 13) "Candy" 14) "98"
4. 內部編碼
相關參數:
zset-max-ziplist-entries 128 zset-max-ziplist-value 64
當有序集合中的元素個數小於zset-max-ziplist-entries
配置的值同時每個元素的大小不超過64位元組時,使用ziplist
作為底層實現,否則使用skiplist
作為底層實現
beh07:6379> zadd zset1 1 tom (integer) 1 beh07:6379> object encoding zset1 "ziplist" beh07:6379> zadd zset2 1 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ' (integer) 1 beh07:6379> object encoding zset2 "skiplist"
(2) skiplist
底層結構
待完善!