Redis常用命令詳細介紹
一、字串
字串鍵是Redis最基本的鍵值對型別,將一個單獨的鍵和一個單獨的值關聯起來。通過字串鍵,不僅可以儲存和讀取字串,如果輸入能被解釋為整數和浮點數,還能執行自增或自減操作。
1、SET:設定字串鍵的值
命令 | SET key value [EX seconds|PX milliseconds] [NX|XX] |
---|---|
效果 | 為字串鍵設定值,如果字串鍵不存在,建立這個字串鍵;如果已經存在,直接更新值。 EX和PX選項設定鍵的生存時間(以秒或毫秒為單位)。當生存時間消耗殆盡後,這個鍵就會被移除。 NX和XX選項決定了是隻進行建立操作還是更新操作。(NX代表not exists) |
返回值 | 如果不使用NX和XX選項,返回OK。 若給定NX,僅當key不存在的情況下執行操作並返回OK,否則返回nil表示操作失敗。若給定XX,僅當key存在的情況下執行操作覆蓋舊值並返回OK,否則返回nil表示操作失敗。 |
注意:同樣可以設定字串鍵值的還有SETNX、SETEX、PSETEX,它們顧名思義很好理解作用,例如SETNX相當於給定了NX選項的SET命令。由於SET本身已經足夠全能,推薦都使用SET命令,其他的命令在遙遠的未來有可能被移除掉。
2、GET:獲取字串鍵的值
命令 | GET key |
---|---|
效果 | 根據字串鍵獲取值 |
返回值 | 鍵對應的值。如果鍵不存在,返回nil。 |
3、GETSET:獲取舊值並設定新值
命令 | GETSET key value |
---|---|
效果 | 先獲取字串鍵當前值,再設定新值,最後返回舊值 |
返回值 | 返回舊值。如果鍵不存在,返回nil。 |
4、MSET、MSETNX、MGET:批量設定獲取值
命令 | MSET key1 value1 [key2 value2 ...] |
---|---|
效果 | 一次為多個字串鍵分別設定值 |
返回值 | 返回OK |
相比SET,一條MSET在代替多條SET的同時只需要客戶端和伺服器進行一次通訊,從而提高了執行效率。
如果你不想覆蓋已經存在的值,使用MSETNX:
命令 | MSETNX key1 value1 [key2 value2 ...] |
---|---|
效果 | 僅當所有key都不存在才一次設定多個鍵值對,否則放棄操作 |
返回值 | 如果所有key都不存在,操作成功,返回1;如果有至少一個key有值,放棄操作,返回0。 |
既然能批量寫,自然也能批量讀:
命令 | MGET key1 [key2 ...] |
---|---|
效果 | 一次獲取多個字串鍵的值 |
返回值 | 返回一個列表,按鍵的順序排列各個值 |
redis> MSET a food b water
OK
redis> MGET b a c
1) "water"
2) "food"
3) (nil)
5、STRLEN:獲取值的位元組長度
命令 | STRLEN key |
---|---|
效果 | 獲取字串值的位元組長度 |
返回值 | 返回一個整數。如果字串鍵不存在,返回0。 |
6、GETRANGE、SETRANGE:根據索引獲取或設定內容
每個字串值都可以通過索引獲取對應的位元組,既可以使用正數索引,也可以使用負數索引(末位為-1,倒數第二個位元組為-2,以此類推)
命令 | GETRANGE key start end |
---|---|
效果 | 獲取值在[start, end]索引範圍的子串 |
返回值 | 返回子串。如果鍵不存在,或者兩個索引都超過了範圍,返回空字串。 |
命令 | SETRANGE key index substr |
---|---|
效果 | 將值從指定index處開始替換。如果index超過了值本身的範圍,空餘部分使用\x00填充 |
返回值 | 返回替換後值的長度 |
7、APPEND:追加新內容到值的末尾
命令 | APPEND key suffix |
---|---|
效果 | 將suffix的內容追加到值的末尾。如果鍵不存在,相當於SET |
返回值 | 返回操作後值的長度 |
8、INCRBY、DECRBY、INCR、DECR、INCRBYFLOAT:對整數和浮點數執行加法和減法操作
如果儲存的字串鍵的值可以被解釋為整數或浮點數,則可以執行加法和減法操作,包括:
1、對於整數而言,必須位於64位長度的有符號整數的範圍內,為-9223372036854775808~9223372036854775807之間。
2、可以用C語言的long double型別儲存的浮點數。
下表列出了一些情形:
值 | 解釋值 |
---|---|
12345 | 整數 |
+888 | 整數 |
-999 | 整數 |
3.14 | 浮點數 |
+2.718 | 浮點數 |
-6.66 | 浮點數 |
-.5 | 浮點數 |
5. | 整數 |
12345678901234567890 | 這個整數太大了,超過了64位有符號整數的範圍,故為字串 |
1.23e4 | Reids無法解釋科學計數法,所以是字串 |
123abc | 字串 |
INCRBY和DECRBY可以對整數值執行加法和減法操作。
命令 | INCRBY key increment |
---|---|
效果 | 為整數加上指定的整數增量,更新之。如果值或增量是浮點數等非整數會報錯。如果鍵不存在,先初始化值為0再執行操作。 |
返回值 | 返回運算後的結果 |
increment可以為負整數,這意味著INCR可以執行減法操作,同樣DECR可以執行加法操作。
INCR和DECR是INCRBY和DECRBY的簡化版,用於對整數值自增1或自減1。
命令 | INCR key |
---|---|
效果 | 整數值自增1。如果值是浮點數等非整數會報錯。如果鍵不存在,先初始化值為0再執行操作。 |
返回值 | 返回運算後的結果 |
以上的四個命令只能用於整數的加減運算,加數或被加數為浮點數都會導致Redis返回錯誤。使用INCRBYFLOAT可以執行整數和浮點數的加減法操作。(沒有DECRBYFLOAT)
命令 | INCRBYFLOAT key increment |
---|---|
效果 | 執行浮點數加減法,更新之。值和increment都可以是整數或浮點數,甚至形如1.23e4這樣用指數表示。如果鍵不存在,先初始化值為0再執行操作。如果執行結果可以表示為整數,則以整數形式儲存。最多保留小數點後17位數字。 |
返回值 | 返回運算後的結果 |
9、總結
- SET、GET、GETSET設定或獲取字串鍵,其中SET包含了豐富的選項,既可以決定是建立還是更新,也可以設定生存時間。這幾個命令都只能操作一個鍵值對。
- MSET、MSETNX、MGET批量操作多個鍵值對,只需要客戶端和伺服器進行一次通訊,從而提高了執行效率。
- 字串值既可以使用正數索引,也可以使用負數索引。
- GETRANGE、SETRANGE、APPEND可以獲取和設定字串值的部分。
- 如果值可以被解釋為數值,可以對數值進行增減操作,如INCRBY、DECRBY、INCR、DECR、INCRBYFLOAT。
- 獲取字串值的位元組長度:STRLEN
二、雜湊(hash)
Redis的雜湊鍵將一個鍵和一個雜湊關聯起來,在雜湊中可以為任意多個欄位(field)分別設定值。比起字串鍵,雜湊鍵能將多個有關聯的資料打包起來儲存。
1、HSET、HSETNX、HGET:設定值或讀取值
命令 | HSET hash field1 value1 [field2 value2...] |
---|---|
效果 | 為一個或多個指定欄位設定值。根據欄位是否存在於雜湊進行建立或覆蓋操作。 |
返回值 | 新增的欄位的數量。這意味著如果全部是覆蓋,將返回0 |
在Redis 4.0.0之前,HSET只能一次給一個欄位設定值。
相比SET,HSET可以一次設定多個值,但沒有諸如NX的選項,此時可以使用HSETNX:
命令 | HSETNX hash field value |
---|---|
效果 | 只在欄位不存在的情況下為其設定值 |
返回值 | 如果欄位不存在,設定成功並返回1,反之不執行操作,返回0 |
沒有HSETEX這樣的命令,這是因為雜湊的生存時間是對整個雜湊而言的,不能單獨為某個欄位設定生存時間。
獲取某個欄位的值,用HGET:
命令 | HGET hash field |
---|---|
效果 | 獲取欄位的值 |
返回值 | 返回欄位的值。如果雜湊或欄位不存在,返回nil。 |
redis> HSET hash1 f1 hello f2 world
2
redis> HSET hash1 f2 World f1 Hello
0
redis> HSETNX hash1 f2 WORLD
0
redis> HGET hash1 f2
"World"
redis> HGET hash1 f
(nil)
2、HMGET:批量操作
命令 | HMGET hash field1 [field2 ...] |
---|---|
效果 | 一次獲取多個欄位的值 |
返回值 | 返回一個數組 |
類似於MSET,雜湊也提供了批量設定欄位的命令HMSET,不過自從Redis 4.0.0增強了HSET之後,官方建議不要繼續使用功能重複的HMSET。(HMSET:明明是我先...)
3、HKEYS、HVALS、HGETALL:獲取所有欄位和值
前面的命令必須指定欄位才能獲取值,那麼有沒有直接獲取整個雜湊所有欄位和值的命令呢?您好,有的。
命令 | HKEYS hash |
---|---|
效果 | 獲取雜湊的所有欄位 |
返回值 | 以列表返回雜湊的所有欄位。如果雜湊不存在,返回空列表 |
命令 | HVALS hash |
---|---|
效果 | 獲取雜湊的所有值 |
返回值 | 以列表返回雜湊的所有值。如果雜湊不存在,返回空列表 |
命令 | HGETALL hash |
---|---|
效果 | 獲取雜湊所有欄位和值 |
返回值 | 以列表返回雜湊的所有欄位和值。如果雜湊不存在,返回空列表 |
redis> HKEYS hash1
1) "f1"
2) "f2"
redis> HVALS hash1
1) "Hello"
2) "World"
redis> HGETALL hash1
1) "f1"
2) "Hello"
3) "f2"
4) "World"
4、HSTRLEN、HLEN:值的位元組長度和雜湊的欄位數量
命令 | HSTRLEN hash field |
---|---|
效果 | 獲取欄位值的位元組長度 |
返回值 | 返回欄位值的位元組長度。如果雜湊或欄位不存在,返回0 |
命令 | HLEN hash |
---|---|
效果 | 獲取雜湊包含的欄位數量 |
返回值 | 返回雜湊包含的欄位數量。如果雜湊不存在,返回0 |
5、HEXISTS、HDEL:欄位是否存在,刪除欄位
命令 | HEXISTS hash field |
---|---|
效果 | 檢查給定欄位是否存在於雜湊中 |
返回值 | 如果雜湊包含給定欄位,返回1,否則返回0。如果雜湊不存在,返回0 |
命令 | HDEL hash field1 [field2 ...] |
---|---|
效果 | 刪除一個或多個給定欄位。本來就不存在的欄位會被忽略。 |
返回值 | 返回刪除成功的欄位的數量。如果雜湊不存在,返回0 |
注意:HDEL刪除的是欄位,如要刪除整個雜湊,使用DEL命令(後面會講到)。
redis> HGETALL hash1
1) "f1"
2) "Hello"
3) "f2"
4) "World"
redis> HDEL hash1 f2 f3
(integer) 1
redis> HKEYS hash1
1) "f1"
6、HINCRBY、HINCRBYFLOAT:對欄位儲存的數字值執行加減操作
命令 | HINCRBY hash field increment |
---|---|
效果 | 對整數值執行加法或減法操作,更新之 |
返回值 | 返回操作結果 |
命令 | HINCRBYFLOAT hash field increment |
---|---|
效果 | 執行浮點數加法或減法操作,更新之 |
返回值 | 返回操作結果 |
Redis沒有提供HINCR、HDECRBY之類的命令。
7、雜湊與字串
由於一個雜湊中可以包含多個欄位,它天然地適合多項關聯資料的存放,而只需要在資料庫中建立一個雜湊鍵。雖然用字串鍵也能達到類似的效果,但更多的鍵將帶來更大的開銷。
另一方面,字串鍵的命令比雜湊更加豐富,功能更加強大。比如字串鍵支援GETRANGE、APPEND命令,這些更加精細的操作是雜湊不具備的,後面還會說到對字串鍵的值按位進行讀寫,即Bitmap。此外,雜湊也無法單獨對某個欄位設定過期時間,一旦某個雜湊鍵過期,它儲存的所有欄位和值都將消失,而使用字串鍵就不會有這樣的顧慮。
在命令上,二者都有很多相似的命令,列舉如下:
字串 | 雜湊 | 對比 |
---|---|---|
SET | HSET | 給字串鍵/雜湊的欄位設定值 |
SETNX | HSETNX | 條件是字串鍵/欄位不存在 |
MSET | HSET、HMSET | 為多個字串鍵/雜湊的多個欄位設定值 |
GET | HGET | 獲取字串鍵/雜湊的欄位的值 |
MGET | HMGET | 獲取多個字串鍵/雜湊的多個欄位的值 |
STRLEN | HSTRLEN | 獲取字串值/欄位值的位元組長度 |
INCRBY | HINCRBY | 對字串值/欄位值進行整數加減操作 |
INCRBYFLOAT | HINCRBYFLOAT | 對字串值/欄位值進行浮點數加減操作 |
EXISTS | HEXISTS | 檢查鍵/欄位是否存在於資料庫/雜湊,EXISTS後面會講 |
DEL | HDEL | 從資料庫/雜湊中刪除鍵/欄位,DEL後面會講 |
此外,雜湊還有:
- HLEN獲取雜湊的欄位數。
- HKEYS、HVALS、HGETALL列出雜湊的所有欄位。
三、列表(list)
Redis的列表是一種線性的有序結構,按照元素被推入的順序儲存元素,當然也可以通過索引進行訪問。
1、LPUSH、LPUSHX、RPUSH、RPUSHX:將元素推入左端或右端
命令 | LPUSH list element1 [element2 ...] |
---|---|
效果 | 將元素推入列表左端。如果推入多個元素,則從左往右依次將所有元素推入左端 |
返回值 | 返回推入操作後列表的元素數量 |
命令 | LPUSHX list element1 [element2 ...] |
---|---|
效果 | 只對已存在的列表執行推入操作 |
返回值 | 返回推入操作後列表的元素數量。如果列表鍵不存在,不執行推入操作,返回0 |
redis> LPUSHX list1 3 4 5
(integer) 0
類似地,RPUSH、RPUSHX將元素推入列表右端。
2、LPOP、RPOP:彈出元素
命令 | LPOP list |
---|---|
效果 | 彈出列表最左端的元素 |
返回值 | 返回彈出的元素。如果列表不存在,返回nil |
類似地,RPOP從右端彈出元素。
注意:可以一次推入多個,但是隻能一次彈出一個。如果想安全彈出多個,可以使用事務。
3、RPOPLPUSH:將右端彈出的元素推入左端
命令 | RPOPLPUSH source destination |
---|---|
效果 | 先使用RPOP將源列表最右端元素彈出,然後使用LPUSH將被彈出的元素推入目標列表左端。源列表和目標列表可以相同,藉此可以構造一個迴圈的列表 |
返回值 | 返回該元素。如果源列表不存在,放棄執行彈出和推入,返回nil |
注:沒有LPOPRPUSH命令。
4、LINDEX、LRANGE:獲取指定索引和索引範圍上的元素
類似於字串的索引,列表包含的每個元素也有對應的正數索引和負數索引。
命令 | LINDEX list index |
---|---|
效果 | 獲取指定索引上的元素 |
返回值 | 返回指定索引上的元素。如果列表不存在或索引越界,返回nil |
命令 | LRANGE list start stop |
---|---|
效果 | 獲取[start, stop]索引範圍上的元素 |
返回值 | 返回指定範圍內的所有元素。如果列表不存在,或兩個索引都越界,或start大於stop,返回空列表。如果只有start越界,start會被修正為0,然後返回對應範圍的元素;同理如果stop越界,修正為-1 |
redis> RPUSH list1 1 2 3
(integer) 3
redis> LRANGE list1 0 -1
1) "1"
2) "2"
3) "3"
redis> LINDEX list1 2
"3"
redis> LINDEX list1 3
(nil)
redis> LRANGE list1 2 5
1) "3"
5、LSET:根據索引設定新元素
命令 | LSET list index element |
---|---|
效果 | 為指定索引設定新元素 |
返回值 | 返回OK。如果列表不存在或給定索引越界,返回錯誤 |
注意:不同於LINDEX,如果LSET的索引越界,將返回錯誤。
6、LINSERT:將元素插入列表
命令 | LINSERT list BEFORE|AFTER target_element new_element |
---|---|
效果 | 將新元素插入目標元素的前面或後面。如果目標元素在列表中有多個,只對從左往右第一個目標元素執行操作 |
返回值 | 返回插入後列表的長度。如果目標元素不存在,返回-1 |
redis> LPUSH list2 hello world hello
(integer) 3
redis> LINSERT list2 BEFORE hello yes
(integer) 4
redis> LRANGE list2 0 -1
1) "yes"
2) "hello"
3) "world"
4) "hello"
7、LREM:移除元素
命令 | LREM list count element |
---|---|
效果 | 移除列表中指定元素element。count的值決定了移除元素的方式: 如果count為0,表示移除所有指定元素; 如果count為正整數,從列表左端開始移除count數量的指定元素; 如果count為負整數,從列表右端開始移除-count數量的指定元素。 |
返回值 | 返回被移除的元素的數量,也就是說如果不存在element或者列表不存在,返回0 |
redis> LPUSH list3 hello world hello foo hello
(integer) 5
redis> LREM list3 -2 hello
(integer) 2
redis> LRANGE list3 0 -1
1) "hello"
2) "foo"
3) "world"
8、LTRIM:修剪列表
命令 | LTRIM list start stop |
---|---|
效果 | 只保留給定範圍[start, stop]內的元素,移除其他元素。 |
返回值 | 返回OK。索引越界不會返回錯誤(例如,如果start超過了陣列的最大索引,將得到一個空列表,也就是說該列表鍵被移除。再如,如果start大於stop,得到的也是一個空列表。如果end超過了陣列的最大索引,將被視為-1) |
9、LLEN:獲取列表的長度
命令 | LLEN list |
---|---|
效果 | 獲取列表的長度 |
返回值 | 返回列表的長度。如果列表不存在,返回0 |
10、BLPOP、BRPOP、BRPOPLPUSH:阻塞式操作
BLPOP和BRPOP是帶有阻塞功能的彈出操作,它接受一個或多個列表以及一個秒級精度的超時時間作為引數。
命令 | BLPOP list1 [list2 ...] timeout |
---|---|
效果 | 從左往右依次檢查給定列表,一旦遇到非空列表就對其執行左端彈出,不會阻塞。如果所有列表都是空的,它將阻塞當前redis-cli客戶端並開始等待,直到有列表變為非空可以彈出元素,或者達到超時時間。如果timeout為0,將永遠阻塞直到可以彈出。 |
返回值 | 如果執行了彈出操作,返回一個二元列表,分別是執行了彈出操作的列表名、彈出的元素本身。如果超時,返回nil。 |
下面的例子中,list4為空而list5非空,客戶端不會阻塞,立即從list5左端彈出c。
redis> LPUSH list5 a b c
(integer) 3
redis> LPUSH list6 c d e
(integer) 3
redis> BLPOP list4 list5 list6 5
1) "list5"
2) "c"
redis> LRANGE list5 0 -1
1) "b"
2) "a"
下面的例子中,list7和list8都是空的,引發當前redis-cli客戶端阻塞,但是在等待的5秒鐘內另一個客戶端向list8中推入了元素a,因此當前客戶端成功彈出元素,並回到非阻塞狀態。注意展示的1.32s的阻塞時長是客戶端為了方便使用者新增的額外資訊,並非BLPOP的返回結果。
redis> BLPOP list7 list8 5 -- 阻塞
1) "list8" -- 彈出元素,解除阻塞
2) "a"
(1.32s)
下面的例子中,list7和list8都是空的,引發當前redis-cli客戶端阻塞,並且在等待的5秒鐘內一直沒有新元素新增至兩個列表,直到超時,並回到非阻塞狀態。
redis> BLPOP list7 list8 5 -- 阻塞
(nil) -- 超時,解除阻塞
(5.29s)
同樣,BRPOPLPUSH是RPOPLPUSH的阻塞版本。
命令 | BRPOPLPUSH source destination timeout |
---|---|
效果 | 如果源列表非空,行為和RPOPLPUSH一樣,彈出源列表最右端元素並推入目標列表左端,最後返回這個元素。如果源列表為空,阻塞客戶端直到源列表可以彈出元素,或者超時。如果timeout為0,將永遠阻塞直到可以彈出 |
返回值 | 如果在超時時間內彈出了元素,返回該元素。如果超時,返回nil |
11、總結
- LPUSH、LPUSHX、RPUSH、RPUSHX推入元素,它們都支援批量操作。
- LINSERT一次插入一個元素。
- LPOP、RPOP一次彈出一個元素,此外還有個較為綜合的RPOPLPUSH。
- LINDEX、LRANGE根據索引或索引範圍獲取元素,LSET根據索引設定元素。
- LREM移除一個或多個元素,LTRIM直接修剪列表。
- LLEN獲取列表長度。
- 有三個阻塞操作:BLPOP、BRPOP、BRPOPLPUSH。
四、集合(set)
Redis的集合鍵可以儲存任意多個各不相同的元素。
雖然列表也可以儲存多個元素,但集合和列表的區別在於:
- 列表可以儲存重複元素,集合只能儲存重複元素,即使新增已存在的元素也會被忽略;
- 列表的儲存是有序的,可以用索引獲取對應元素,集合是無序的,沒有索引的概念。
1、SADD、SREM:新增、移除元素
命令 | SADD set member1 [member2 ...] |
---|---|
效果 | 將一個或多個元素新增到集合中。會忽略已經存在的元素 |
返回值 | 返回成功新增的新元素數量 |
命令 | SREM set member1 [member2 ...] |
---|---|
效果 | 從集合中移除一個或多個元素。忽略不存在的元素 |
返回值 | 返回被移除的元素數量 |
redis> SADD set1 a b c
(integer) 3
redis> SADD set1 b d e
(integer) 2
redis> SREM set1 a d f
(integer) 2
2、SMOVE:將元素從一個集合移動到另一個集合
命令 | SMOVE source destination member |
---|---|
效果 | 將元素從源集合移動到目標集合 |
返回值 | 移動操作成功執行返回1。如果源集合不存在,或者source不在源集合中,返回0。(如果要移動的元素已經存在於目標集合,仍然會從源集合中移除,最終返回1) |
3、SCARD:獲取集合包含的元素數量
命令 | SCARD set |
---|---|
效果 | 獲取給定集合包含的元素數量 |
返回值 | 返回集合包含的元素數量 |
4、SISMEMBER:檢查給定元素是否存在於集合
命令 | SISMEMBER set member |
---|---|
效果 | 檢查給定元素是否存在於集合 |
返回值 | 存在返回1,不存在或集合本身不存在返回0 |
5、SMEMBERS:獲取集合包含的所有元素
命令 | SMEMBERS set |
---|---|
效果 | 獲取集合包含的所有元素 |
返回值 | 返回集合包含的所有元素。如果集合不存在,返回空集合 |
6、SRANDMEMBER、SPOP:隨機獲取元素
命令 | SRANDMEMBER set [count] |
---|---|
效果 | 從集合中隨機獲取指定數量的元素。如果不指定count,就只獲取一個元素。SRANDMEMBER不會將元素從集合中刪除。 |
返回值 | 如果沒有給定count,返回nil或單獨的元素。如果給定count,返回空列表或者列表,列表元素具體由count的值決定: 如果count大於集合長度,返回所有元素。 如果count為0,返回空集合。 如果count為負數,隨機返回-count個元素,並且這些元素中允許出現相同的值。(也就是說,如果-count大於集合長度,仍然會返回-count個元素,而不是所有元素) |
命令 | SPOP set [count] |
---|---|
效果 | 從集合中隨機移除指定數量的元素。如果不給定count,只移除一個元素。count不能為負數。 |
返回值 | 返回這些被移除的元素。如果count為0,不執行移除操作,返回空集合。 |
SPOP與SRANDMEMBER非常相似,主要區別在於SPOP會移除被隨機選中的元素,而SRANDMEMBER不會。
7、SINTER、SINTERSTORE、SUNION、SUNIONSTORE、SDIFF、SDIFFSTORE:多個集合的交集、並集、補集計算
SINTER和SINTERSTORE對一個或多個集合執行交集計算。set1和set2取交集,結果再和set3取交集,以此類推。特別地,如果只給定了一個集合,直接返回這個集合,此時相當於SMEMBERS。
命令 | SINTER set1 [set2 ...] |
---|---|
效果 | 對集合執行交集計算 |
返回值 | 返回交集結果的所有元素。 |
redis> SADD set2 a b c
(integer) 3
redis> SADD set3 c
(integer) 1
redis> SADD set4 c d e
(integer) 3
redis> SINTER set1 set2 set3
1) "c"
SINTERSTORE還能將計算結果儲存到指定鍵裡面:
命令 | SINTERSTORE destination set1 [set2 ...] |
---|---|
效果 | 對集合執行交集計算並把結果儲存到目的集合中。如果目的鍵已經存在,將會被覆蓋 |
返回值 | 返回結果集合的元素數量 |
SUNION和SUNIONSTORE對一個或多個集合執行並集計算。
命令 | SUNION set1 [set2 ...] |
---|---|
效果 | 對集合執行並集計算 |
返回值 | 返回並集結果的所有元素 |
命令 | SUNIONSTORE destination set1 [set2 ...] |
---|---|
效果 | 對集合執行交集計算並把結果儲存到目的集合中。如果目的鍵已經存在,將會被覆蓋 |
返回值 | 返回結果集合的元素數量 |
SDIFF和SDIFFSTORE對一個或多個集合執行並集計算。
命令 | SDIFF set1 [set2 ...] |
---|---|
效果 | 對集合執行差集計算:首先計算set1 - set2,然後對所得集合s執行s - set3,以此類推 |
返回值 | 返回差集結果的所有元素 |
命令 | SDIFFSTORE destination set1 [set2 ...] |
---|---|
效果 | 對集合執行差集計算並把結果儲存到目的集合中 |
返回值 | 返回結果集合的元素數量 |
8、總結
- SADD新增元素,SREM移除元素,支援操作多個元素。
- SMOVE在集合間移動一個元素。
- SISMEMBER檢查存在,SCARD獲取總數量,SMEMBERS獲取所有元素。
- SRANDMEMBER、SPOP都能隨機獲取一個或多個元素,後者還會移除元素。
- 集合之間支援交集、並集、差集運算。
五、有序集合(zset)
有序集合同時具有有序和集合兩種性質。在有序集合中,每個元素由一個成員和一個與成員關聯的分值組成,其中成員以字串方式儲存,分值以64位雙精度浮點數格式儲存。每個成員是獨一無二的,不會重複,並且每個成員按照自己的分值大小進行排序。如果分值相同,則按成員在字典序中的大小排序。分值不僅可以是數字,也可以是字串"+inf"或者"-inf",分別表示無窮大和無窮小。
1、ZADD:新增或更新成員
命令 | ZADD zset [NX|XX] [CH] [INCR] score1 member1 [score2 member2 ...] |
---|---|
效果 | 新增或更新成員。如果zset或member不存在,新增成員以及分值。如果member已經存在且與給定的不一致,更新分值。 XX和NX選項限制只進行新增或更新操作:如果給定了XX選項,則只更新已經存在於zset中的成員的分值,忽略不存在的;如果給定NX選項,只新增不存在於zset的成員和分值,忽略已經存在的成員。 CH選項決定了返回值是否統計更新分值的數量。(CH代表changed) INCR選項使得ZADD的行為類似於ZINCRBY,如果給定INCR選項,那麼只能傳入一對score和member,效果是對給定的成員的分值進行自增或自減操作 |
返回值 | 返回成功新增的新成員的數量(不含更新分值的)。如果給定CH選項,則返回被修改的成員的數量,既包括新新增的,也包括更新分值的。如果給定INCR選項,返回進行運算後的分值或者nil(使用了NX或XX選項且操作被忽略) |
redis> ZADD zset1 1 one 2 two
(integer) 2
redis> ZADD zset1 2 one 3 three 4 four
(integer) 2
redis> ZADD zset1 CH 2.5 one 3.5 four 5 five
(integer) 3
redis> ZADD zset1 NX 1 one
(integer) 0
redis> ZADD zset1 INCR -1.5 one
"1"
2、ZREM:移除指定成員
命令 | ZREM zset member1 [member2 ...] |
---|---|
效果 | 移除一個或多個成員以及相關聯的分值。如果給定的某個成員不存在,將被忽略。 |
返回值 | 返回移除的數量 |
3、ZSCORE:獲取成員的分值
命令 | ZSCORE zset member |
---|---|
效果 | 獲取成員的分值 |
返回值 | 返回成員的分值。如果zset不存在,或者member不存在,返回nil |
4、ZCARD:獲取有序集合的大小
命令 | ZCARD zset |
---|---|
效果 | 獲取有序集合包含的成員數量 |
返回值 | 返回zset包含的成員數量。如果集合不存在,返回0 |
5、ZINCRBY:對成員的分值執行增減操作
命令 | ZINCRBY zset increment member |
---|---|
效果 | 對成員的分值執行自增或自減操作並更新之。如果zset或者member不存在,相當於執行ZADD zset increment member。 |
返回值 | 返回運算後的分值 |
6、ZRANGE、ZREVRANGE:根據索引範圍獲取範圍內的成員
類似於列表的索引,ZRANGE和ZREVRANGE既可以接受正數索引,也可以接受負數索引。預設成員按照分值的大小升序排序,分值相同的成員再按字典序升序排列。
命令 | ZRANGE zset start end [WITHSCORES] |
---|---|
效果 | 以升序排列獲取指定索引範圍[start, end]內的成員 |
返回值 | 返回範圍內的成員。如果給定WITHSCORES選項,則按照member1,score1的形式同時返回成員和關聯分值。索引越界不會產生異常。 |
ZREVRANGE返回的是降序排名,此時成員按照分值的大小降序排序,並且分值相同的成員也會按字典序降序排列。
命令 | ZREVRANGE zset start end [WITHSCORES] |
---|---|
效果 | 以降序排列獲取指定索引範圍[start, end]內的成員 |
返回值 | 返回範圍內成員。如果給定WITHSCORES選項,則返回成員的同時也會返回關聯的分值。 |
redis> ZADD zset2 1 a 1 b 1 c 2 e
(integer) 4
redis> ZRANGE zset2 0 -1
1) "a"
2) "b"
3) "c"
4) "e"
redis> ZRANGE zset2 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "1"
5) "c"
6) "1"
7) "e"
8) "2"
redis> ZREVRANGE zset2 0 -1
1) "e"
2) "c"
3) "b"
4) "a"
7、ZREMRANGEBYRANK:根據索引範圍移除指定範圍內的成員
命令 | ZREMRANGEBYRANK zset start end |
---|---|
效果 | 從zset中移除指定索引範圍[start, end]內的成員 |
返回值 | 返回被移除成員的數量 |
8、ZRANK、ZREVRANK:根據成員獲取索引
ZRANK和ZRANGE正好相反,根據單個成員獲取索引。
命令 | ZRANK zset member |
---|---|
效果 | 獲取成員在zset中的升序排名(即索引),序號從0開始。 |
返回值 | 返回成員在zset中的索引。如果zset或member不存在,返回nil |
ZREVRANK類似於ZRANK,只不過返回的是降序排名。
命令 | ZREVRANK zset member |
---|---|
效果 | 獲取成員在zset中的降序排名,序號從0開始。 |
返回值 | 返回成員在zset中的降序排名。如果zset或member不存在,返回nil |
redis> ZREVRANGE zset2 0 -1
1) "e"
2) "c"
3) "b"
4) "a"
redis> ZREVRANK zset2 b
(integer) 2
9、ZRANGEBYSCORE、ZREVRANGEBYSCORE:根據分值獲取指定範圍內的成員
zset中每個成員和索引以及分值繫結,既能通過索引獲取成員,也能通過分值獲取成員。分值的範圍比較複雜:
- 和索引範圍一樣,分值範圍預設也是閉區間;
- 如果想使用開區間,在分值引數的前面加一個小括號(。例如ZRANGEBYSCORE zset (1 5表示1 < score <= 5,再如ZRANGEBYSCORE zset (5 (10表示5 < score < 10;
- 還可以使用-inf和+inf表示無窮小和無窮大,用於只需要分值範圍的上限和下限時。
命令 | ZRANGEBYSCORE zset min max [WITHSCORES] [LIMIT offset count] |
---|---|
效果 | 以升序排列獲取zset中分值介於min和max內的成員。使用LIMIT選項可以從結果中只取一部分,例如LIMIT 1 3表示取第2-4個結果。 |
返回值 | 返回範圍內成員。如果給定WITHSCORES選項,則返回成員的同時也會返回關聯的分值。 |
ZREVRANGEBYSCORE正好相反。需要注意的是,先接受max引數再接受min引數。
命令 | ZREVRANGEBYSCORE zset max maminx [WITHSCORES] [LIMIT offset count] |
---|---|
效果 | 以升序排列獲取zset中分值介於min和max內的成員。使用LIMIT選項可以從結果中只取一部分,例如LIMIT 1 3表示取第2-4個結果。 |
返回值 | 返回範圍內成員。如果給定WITHSCORES選項,則返回成員的同時也會返回關聯的分值。 |
redis> ZADD zset3 1.3 one 2.4 two 4.1 four 6.2 six 2.4 two2
(integer) 5
redis> ZRANGEBYSCORE zset3 -inf +inf
1) "one"
2) "two"
3) "two2"
4) "four"
5) "six"
redis> ZREVRANGEBYSCORE zset3 +inf -inf
1) "six"
2) "four"
3) "two2"
4) "two"
5) "one"
redis> ZRANGEBYSCORE zset3 1 6 LIMIT 1 2 -- 取升序的第二和第三個
1) "two"
2) "two2"
10、ZREMRANGEBYSCORE:根據分值移除指定範圍內的成員
命令 | ZREMRANGEBYSCORE zset min max |
---|---|
效果 | 從升序排列的zset中移除指定分值範圍min和max內的成員。分值範圍參考ZRANGEBYSCORE |
返回值 | 返回被移除成員的數量 |
11、ZCOUNT:統計指定分值範圍內的成員數量
命令 | ZCOUNT zset min max |
---|---|
效果 | 統計指定分值範圍內的成員數量。分值範圍參考ZRANGEBYSCORE |
返回值 | 返回指定分值範圍內的成員數量 |
12、ZRANGEBYLEX、ZREVRANGEBYLEX:根據字典序獲取指定範圍內的成員
如果有序集合中所有成員的分值都相同,它相當於一個按字典序自動排列的列表,此時ZRANGEBYSCORE這樣的命令已經沒有意義。Redis提供了諸如ZRANGEBYLEX這樣的命令,根據字典序進行排序、刪除、計數等操作。特別地,它沒有WITHSCORES選項。
字典序的範圍必須是以下四種之一:
- 以小括號(開頭的值,表示開區間;
- 以中括號[開頭的值,表示閉區間;
- 減號-,表示無窮小;
- 加號+,表示無窮大。
注意:如果有序集合中的成員分值不同,返回值將變得不可預測。
命令 | ZRANGEBYLEX zset min max [LIMIT offset count] |
---|---|
效果 | 以字典序獲取介於min和max內的成員。使用LIMIT選項可以從結果中只取一部分 |
返回值 | 返回範圍內成員 |
和ZREVRANGEBYSCORE一樣,ZREVRANGEBYLEX也是先接受max引數再接受min引數。
命令 | ZREVRANGEBYLEX zset max min [LIMIT offset count] |
---|---|
效果 | 以逆字典序獲取介於min和max內的成員。使用LIMIT選項可以從結果中只取一部分 |
返回值 | 返回範圍內成員 |
redis> ZADD zset4 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
redis> ZREVRANGEBYLEX zset4 [c -
1) "c"
2) "b"
3) "a"
redis> ZRANGEBYLEX zset4 (f +
1) "g"
redis> ZRANGEBYLEX zset4 [aaa (d
1) "b"
2) "c"
13、ZREMRANGEBYLEX:根據字典序移除指定範圍內的成員
命令 | ZREMRANGEBYLEX zset min max |
---|---|
效果 | 移除指定字典序範圍min和max內的成員。字典序範圍參考ZRANGEBYLEX |
返回值 | 返回被移除成員的數量 |
14、ZLEXCOUNT:根據字典序統計位於指定範圍內的成員數量
命令 | ZCOUNT zset min max |
---|---|
效果 | 統計位於字典序指定範圍內的成員數量。字典序範圍參考ZRANGEBYLEX |
返回值 | 返回位於字典序指定範圍內的成員數量 |
15、ZUNIONSTORE、ZINTERSTORE:並集和交集運算
命令 | ZUNIONSTORE destination numzsets zset1 [zset2 ...] [WEIGHTS weight1 [weight2 ...]] [AGGREGATE SUM|MIN|MAX] |
---|---|
效果 | 進行並集運算並存儲到目標有序集合中,如果destination鍵已經存在,將會被覆蓋。 取並集的成員的分值由原來的多個有序集合的成員的分值相加得到。如果給定了AGGREGATE選項,可以改變分值的計算方式:SUM(預設)、MIN、MAX。 numzsets指定參與計算的有序集合數量,必須和zset的數量一致否則報錯。 如果使用WEIGHTS選項,需要為每個給定的有序集合分別設定一個權重,新分值由成員的分值與權重之積再聚合計算得到。可以使用集合作為並集運算的輸入,集合的分值視為1 |
返回值 | 返回計算結果包含的成員數量 |
下面的例子,分別用兩種聚合方式求出了並集
redis> ZADD zset5 1 a 2 b 3 c
(integer) 3
redis> ZADD zset6 2 a 5 c 8 d
(integer) 3
redis> ZUNIONSTORE store1 2 zset5 zset6 WEIGHTS 3 2
(integer) 4
redis> ZRANGE store1 0 -1
1) "b"
2) "a"
3) "d"
4) "c"
redis> ZRANGE store1 0 -1 WITHSCORES
1) "b"
2) "6" -- 6 = 2 * 3
3) "a"
4) "7" -- 7 = 1 * 3 + 2 * 2
5) "d"
6) "16"
7) "c"
8) "19"
redis> ZUNIONSTORE store2 2 zset5 zset6 WEIGHTS 3 2 AGGREGATE MIN
(integer) 4
redis> ZRANGE store2 0 -1 WITHSCORES
1) "a"
2) "3" -- 3 = min(1 * 3, 2 * 2)
3) "b"
4) "6"
5) "c"
6) "9"
7) "d"
8) "16"
下面的例子,將一個有序集合和一個集合取並集,集合中成員的分值視為1。
redis> SMEMBERS set1
1) "b"
2) "e"
3) "c"
redis> ZRANGE zset5 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
redis> ZUNIONSTORE store3 2 zset5 set1
(integer) 4
redis> ZRANGE store3 0 -1 WITHSCORES
1) "a"
2) "1"
3) "e"
4) "1"
5) "b"
6) "3"
7) "c"
8) "4"
ZINTERSTORE對有序集合取交集計算。
命令 | ZINTERSTORE destination numzsets zset1 [zset2 ...] [WEIGHTS weight1 [weight2 ...]] [AGGREGATE SUM|MIN|MAX] |
---|---|
效果 | 進行交集運算並存儲到目標有序集合中,其他類似ZUNIONSTORE |
返回值 | 返回計算結果包含的成員數量 |
16、ZPOPMAX、ZPOPMIN:彈出分值最高和最低的成員
命令 | ZPOPMAX zset [count] |
---|---|
效果 | 彈出count個分值最高的成員,不給定count則彈出1個 |
返回值 | 返回被彈出的這些成員和對應分值 |
命令 | ZPOPMIN zset [count] |
---|---|
效果 | 彈出count個分值最低的成員,不給定count則彈出1個 |
返回值 | 返回被彈出的這些成員和對應分值 |
17、BZPOPMAX、BZPOPMIN:阻塞式彈出分值最高和最低的成員
命令 | BZPOPMAX zset1 [zset2 ...] timeout |
---|---|
效果 | 依次檢查給定的所有zset並對第一個非空zset彈出其內最大分值的元素。如果所有zset都沒有可彈出的元素,就阻塞客戶端直到可以彈出或超時。如果timeout設定為0,表示一直阻塞,直到可彈出元素出現為止。 |
返回值 | 成功彈出元素後返回一個三元列表:被彈出元素所在zset名、被彈出元素的成員、被彈出成員的分值。如果超時,返回nil。 |
命令 | BZPOPMIN zset1 [zset2 ...] timeout |
---|---|
效果 | 類似於BZPOPMAX,只是彈出的是分值最低的成員 |
返回值 | 同BZPOPMAX |
redis> ZRANGE zset5 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
redis> BZPOPMIN zset5 4
1) "zset5"
2) "a"
3) "1"
18、總結
- ZADD新增一個或多個成員-分值對,ZREM移除一個或多個成員。ZADD還能當ZINCRBY用。
- 用單個成員能做什麼?獲取分值、更新分值、獲取索引,ZSCORE、ZINCRBY、ZRANK、ZREVRANK。
- 用索引能做什麼?獲取和移除,ZRANGE、ZREVRANGE、ZREMRANGEBYRANK。
- 分值可以使用開區間、-inf和+inf。用分值能做什麼?獲取、移除、計數,ZRANGEBYSCORE、ZREVRANGEBYSCORE、ZREMRANGEBYSCORE、ZCOUNT。
- 獲取集合大小:ZCARD。
- 字典序相關:ZRANGEBYLEX、ZREVRANGEBYLEX、ZREMRANGEBYLEX、ZLEXCOUNT,僅用於分值都相同。
- 並集和交集運算:ZUNIONSTORE、ZINTERSTORE。
- 阻塞或非阻塞彈出分值最高最低成員:ZPOPMAX、ZPOPMIN、BZPOPMAX、BZPOPMIN。
六、HyperLogLog
以下引用自Redis中文網:
Redis HyperLogLog是用來做基數統計的演算法,HyperLogLog的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定的、並且是很小的。
在 Redis 裡面,每個HyperLogLog鍵只需要花費12 KB記憶體,就可以計算接近2^64個不同元素的基數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。
但是,因為HyperLogLog只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以HyperLogLog不能像集合那樣,返回輸入的各個元素。
什麼是基數?
比如資料集 {1, 3, 5, 7, 5, 7, 8},那麼這個資料集的基數集為 {1, 3, 5 ,7, 8},基數(不重複元素)為5。基數估計就是在誤差可接受的範圍內,快速計算基數。
1、PFADD:新增指定元素到HyperLogLog中
命令 | PFADD hyperloglog element1 [element2 ...] |
---|---|
效果 | 將元素新增到HyperLogLog集合中 |
返回值 | 如果給定元素中出現了至少一個新元素,返回1,表示因為新元素的新增使得計算出的近似基數發生變化。如果沒有新元素,返回0,表示計算出的近似基數不變 |
redis> PFADD hll1 a b c d e f g
(integer) 1
redis> PFCOUNT hll1
(integer) 7
2、PFCOUNT:返回集合的近似基數
命令 | PFCOUNT hyperloglog1 [hyperloglog2 ...] |
---|---|
效果 | 獲取集合的近似基數。如果傳入多個HyperLogLog,先進行並集計算再求並集集合的近似基數 |
返回值 | 返回集合的近似基數 |
redis> PFADD hll2 hello world yes
(integer) 1
redis> PFADD hll2 yes yes yes
(integer) 0
redis> PFADD hll3 a b c d
(integer) 1
redis> PFCOUNT hll2 hll3
(integer) 7
3、PFMERGE:計算並存儲多個HyperLogLog的並集
命令 | PFMERGE destination hyperloglog1 [hyperloglog2 ...] |
---|---|
效果 | 對多個給定的hyperloglog執行並集計算,把並集結果儲存到destination中 |
返回值 | 返回OK |
PFCOUNT在計算多個HyperLogLog的並集後會將其儲存到一個臨時的HyperLogLog中再得到近似基數,最後將臨時的HyperLogLog刪除掉。而PFMERGE會儲存起來。
七、點陣圖(bitmap)
Redis的點陣圖是由多個二進位制位組成的陣列,每個二進位制位有自己的