第二章 Redis API的使用 單執行緒介紹【Redis入門教程】

薛8發表於2019-02-13
image

Redis入門教程目錄【Redis入門教程目錄】

資料結構和內部編碼

通過這部分讓大家對Redis的五種資料結構有初步的認識,對於Redis來說,每一種資料結構都有著自己的內部編碼,而且是多種實現的,這樣Redis會在合適的場景選擇合適的內部編碼,通過OBJECT ENCODING [key]可以參看指定key的內部編碼。
這樣做的好處:
a. 改進內部編碼,對外的資料結構和命令沒有影響,對使用者提供黑箱模型。
b. 多種內部編碼可在不同場景下發揮各自的優勢。如:ziplist比較節約記憶體,但是元素比較多的時候,效能會有所下降,此時Redis會將編碼自動轉換為linkedlist,效能會有所改善。

image

單執行緒

瞭解Redis的單執行緒架構,有助於大家對Redis的進一步學習和排解問題。

image

Redis處理網路請時候的求單執行緒可以抽象成這樣,通向Redis的路只有一條,且這條路是個單車道,只容的下一輛車同時使用,而我們使用的Redis命令即為這些車輛,當我們執行多個命令的時候,只有等第一個命令執行完成了後面的命令才會執行,否則會一直處於等待狀態。
image
Redis單執行緒的架構需要我們注意幾點
a. 一次只執行一條命令
b. 拒絕長(慢)命令(keys、flushall、flushdb、slow lua script、mutil/exec、operate、big value)
至於為什麼單執行緒還這麼快,這裡有個原因,Redis客戶端的到Redis伺服器的網路請求採用了多路I/O複用模型(非阻塞I/O),利用selectpollepoll可以同時監聽多個流的I/O(客戶端到伺服器的網路請求)事件的能力,在空閒的時候,會把當前執行緒阻塞掉,當有一個或者多個流有I/O事件時,就從阻塞態中喚醒,輪訓一遍所有的流並且依次處理就緒的流。這樣就算出現有的流的I/O因為網路原因很慢,也不會影響別的流的I/O(非阻塞),因為是輪訓所有的流的I/O。這裡的“多路”指的是多個網路連線,“複用”指的是複用同一個執行緒。 第二章 Redis API的使用 單執行緒介紹【Redis入門教程】

通用命令

Redis一些通用命令,比如刪除一個鍵、計算資料庫的大小、設定鍵的過期時間等,這些命令有很多,這裡主要介紹7個,完整的命令大家可以參考官方文件。

  1. KEYS [pattern]
    時間複雜度為O(N)N為資料庫中Key的數量。 這個命令由於時間複雜度為O(N)所以一般生產環境不使用,如果需要遍歷全部資料,可以使用Scan命令,時間複雜度為O(1)。
    查詢所有符合給定模式patternkey,比如說:
  • KEYS *匹配資料庫中所有的key
  • KEYS h?llo匹配hellohallokey
  • KEYS h*llo匹配hllohaaaaaallokey
  • KEYS h[abe]llo匹配hallohbllohello
    返回值: 符合給定模式的key列表。
  1. DBSIZE
    時間複雜度為O(1),計算的時候不是掃描整個表,因為Redis有個計數器,實時更新Key總數。
    查詢返回當前資料庫的key的數量。
    返回值: 返回當前資料庫的key的數量。
    程式碼演示:
redis> DBSIZE
(integer) 5

redis> SET new_key "hello_moto"     # 增加一個 key 試試
OK

redis> DBSIZE
(integer) 6
複製程式碼
  1. EXISTS key
    時間複雜度為O(1)
    檢查給定key是否存在。
    返回值:key存在,返回1,不存在返回0

  2. DEL key [key ...]
    時間複雜度為O(N)N為被刪除的key的數量,其中刪除單個字串型別的key,時間複雜度為O(1);刪除單個列表、集合、有序集合或雜湊表型別的key,時間複雜度為O(M)M為以上資料結構內的元素數量。
    刪除指定的一個或者多個key,不存在的key會被忽略。
    返回值: 被刪除的key的數量。

  3. EXPIRE key seconds
    時間複雜度為O(1)
    為給定的key設定生存時間,當key過期時,它會被自動刪除
    返回值: 設定成功返回1,當key不存在或者設定失敗的時候返回0

  4. PERSIST key
    時間複雜度為O(1)
    移除給定key的生存時間,將這個key轉換成持久的。
    返回值: 當生存時間移除成功時,返回1,如果key不存在或者沒有設定生存時間,返回0
    程式碼演示:

redis> SET mykey "Hello"
OK

redis> EXPIRE mykey 10  # 為 key 設定生存時間
(integer) 1

redis> TTL mykey
(integer) 10

redis> PERSIST mykey    # 移除 key 的生存時間
(integer) 1

redis> TTL mykey
(integer) -1
複製程式碼
  1. TTL key
    時間複雜度O(1)
    以秒為單位,返回給定key的剩餘生存時間(TTL,time to live)。
    返回值:key不存在時,返回-2,當key存在但是沒有設定生存時間時,返回-1,否則返回key的剩餘生存時間。
    程式碼演示:
# 不存在的 key

redis> FLUSHDB
OK

redis> TTL key
(integer) -2


# key 存在,但沒有設定剩餘生存時間

redis> SET key value
OK

redis> TTL key
(integer) -1


# 有剩餘生存時間的 key

redis> EXPIRE key 10086
(integer) 1

redis> TTL key
(integer) 10084
複製程式碼

五種資料結構

這裡介紹Redis的五種資料結構String(字串)、Hash(雜湊)、List(列表)、Set(集合)、Zset(即Sorted Set有序集合)的結構和一些命令。

字串

字串是Redis中最基礎的資料結構。

鍵值結構

字串的值雖然是字串但是可以儲存很多種型別的資料,如:簡單的字串、JSON、XML、數字、二進位制等。需要注意一點的是,Redis中字串型別的值最大能儲存512MB。

image

命令

  1. SET key value [EX seconds] [PX milliseconds] [NX|XX]
    時間複雜度O(1)
    將字串值value關聯到key,如果key已經持有其他值,SET就覆寫舊值,無視型別,當SET命令對一個帶有生存時間(TTL)的鍵進行設定之後,該鍵原有的TTL將被清除。
    可選引數:
  • EX seconds:將鍵的過期時間設定為seconds秒。 執行SET key value EX seconds的效果等同於執行SETEX key seconds value
  • PX milliseconds:將鍵的過期時間設定為milliseconds毫秒。執行SET key value PX milliseconds的效果等同於執行PSETEX key milliseconds value
  • NX:只在鍵不存在時,才對鍵進行設定操作。執行SET key value NX的效果等同於執行SETNX key value
  • XX:只在鍵已經存在時,才對鍵進行設定操作。

因為SET命令可以通過引數來實現SETNXSETEX以及PSETEX命令的效果,所以Redis將來的版本可能會移除並廢棄SETNXSETEXPSETEX這三個命令。

返回值: 在Redis 2.6.12版本以前,SET命令總是返回OK
從Redis 2.6.12版本開始,SET命令只在設定操作成功完成時才返回OK;如果命令使用了NX或者XX選項, 但是因為條件沒達到而造成設定操作未執行, 那麼命令將返回空批量回復(NULL Bulk Reply)。
程式碼演示:

# 使用 EX 選項
redis> SET key-with-expire-time "hello" EX 10086
OK

redis> GET key-with-expire-time
"hello"

redis> TTL key-with-expire-time
(integer) 10069
複製程式碼
  1. GET key
    時間複雜度O(1)
    獲取與鍵key相關聯的字串值。
    返回值:
    如果鍵key不存在,那麼返回特殊值nil;否則,返回鍵key的值。
    如果鍵key的值並非字串型別,那麼返回一個錯誤,因為GET命令只能用於字串值。
    程式碼演示:
redis> GET db
(nil)

redis> SET db redis
OK

redis> GET db
"redis"
複製程式碼
  1. DEL key [key ...]
    時間複雜度為O(N)N為被刪除的key的數量,其中刪除單個字串型別的key,時間複雜度為O(1);刪除單個列表、集合、有序集合或雜湊表型別的key,時間複雜度為O(M)M為以上資料結構內的元素數量。
    刪除指定的一個或者多個key,不存在的key會被忽略。
    返回值: 被刪除的key的數量。
    程式碼演示:
# 同時刪除多個 key

redis> SET name "redis"
OK

redis> SET type "key-value store"
OK

redis> SET website "redis.com"
OK

redis> DEL name type website
(integer) 3
複製程式碼
  1. MSET key value [key value ...]
    時間複雜度O(N),其中N為被設定的鍵數量。
    同時為多個鍵設定值。如果某個給定鍵已經存在,那麼MSET將使用新值去覆蓋舊值,如果這不是你所希望的效果,請考慮使用MSETNX命令,這個命令只會在所有給定鍵都不存在的情況下進行設定。MSET是一個原子性(atomic) 操作,所有給定鍵都會在同一時間內被設定,不會出現某些鍵被設定了但是另一些鍵沒有被設定的情況。
    返回值: MSET命令總是返回OK
    程式碼演示:
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK

redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
複製程式碼
  1. MSETNX key value [key value ...]
    時間複雜度O(N),其中N為被設定的鍵數量。
    當且僅當所有給定鍵都**不存在時,為所有給定鍵設定值。即使只有一個給定鍵已經存在,MSETNX命令也會拒絕執行對所有鍵的設定操作。MSETNX是一個原子性(atomic) 操作,所有給定鍵要麼就全部都被設定,要麼就全部都不設定,不可能出現第三種狀態。
    返回值: 當所有給定鍵都設定成功時,命令返回1;如果因為某個給定鍵已經存在而導致設定未能成功執行,那麼命令返回0
    程式碼演示:
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1

redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
複製程式碼
  1. MGET key [key ...]
    時間複雜度O(N),其中N為給定鍵的數量。
    返回給定的一個或多個字串鍵的值。如果給定的字串鍵裡面,有某個鍵不存在,那麼這個鍵的值將以特殊值nil表示。
    返回值: MGET命令將返回一個列表,列表中包含了所有給定鍵的值。
    程式碼演示:
redis> SET redis redis.com
OK

redis> SET mongodb mongodb.org
OK

redis> MGET redis mongodb
1) "redis.com"
2) "mongodb.org"

redis> MGET redis mongodb mysql     # 不存在的 mysql 返回 nil
1) "redis.com"
2) "mongodb.org"
3) (nil)
複製程式碼
  1. N次GET和一次MGET對比
    總所周知,Redis採用的是客戶端-伺服器方式,即在一次round trip中,客戶端傳送一條命令,伺服器解析命令並執行,然後向客戶端返回結果,如果執行N條命令,就是N個請求N次執行N個返回

    image
    如果我們把N條命令都放在一個請求中,一次請求多個執行一個返回,那麼就可以大大的降低網路時間的開銷,這個也就是Redis的pipline
    image

  2. N次SET和一次MSET對比
    同7

雜湊

Redis的雜湊是鍵值對的集合,是字串欄位和字串值之間的對映。

鍵值結構

Hash資料結構即資料儲存為fieldvalue的格式儲存

image
可以將fieldvalue看成一對鍵值對結構
image

命令

  1. HSET key field value
    時間複雜度O(1)
    將雜湊表key中域field的值設定為value,如果給定的雜湊表不存在,那麼一個新的雜湊表將被建立並執行HSET操作,如果域field已存在於雜湊表中,那麼它的舊值將被新值value覆蓋。
    返回值:HSET命令在雜湊表中新建立field域併成功為它設定值時,命令返回1;如果域field已經存在於雜湊表,並且HSET命令成功使用新值覆蓋了它的舊值,那麼命令返回0
    程式碼演示:
redis> HSET website google "www.g.cn"
(integer) 1

redis> HGET website google
"www.g.cn"
複製程式碼
  1. HGET key field
    時間複雜度O(1)
    返回雜湊表中給定域的值。
    返回值: HGET命令在預設情況下返回給定域的值,如果給定域不存在於雜湊表中,又或者給定的雜湊表並不存在,那麼命令返回nil程式碼演示:
redis> HSET homepage redis redis.com
(integer) 1

redis> HGET homepage redis
"redis.com"
複製程式碼
  1. HGETALL key
    時間複雜度O(N)N為雜湊表的大小,謹慎用。
    返回雜湊表的所有的域和值,在返回值裡,緊跟每個域(field name)之後是域的值(value),所以返回值的長度是雜湊表大小的兩倍。
    返回值: 以列表形式返回雜湊表的域和域的值,若key不存在,返回空列表。 程式碼演示:
redis> HSET people jack "Jack Sparrow"
(integer) 1

redis> HSET people gump "Forrest Gump"
(integer) 1

redis> HGETALL people
1) "jack"          # 域
2) "Jack Sparrow"  # 值
3) "gump"
4) "Forrest Gump"
複製程式碼
  1. HDEL key field [field ...]
    時間複雜度O(N)N為要刪除的域的數量。
    刪除雜湊表key中的一個或多個指定域,不存在的域將被忽略。
    返回值: 被成功移除的域的數量,不包括被忽略的域。
    程式碼演示:
# 測試資料

redis> HGETALL abbr
1) "a"
2) "apple"
3) "b"
4) "banana"
5) "c"
6) "cat"
7) "d"
8) "dog"


# 刪除單個域

redis> HDEL abbr a
(integer) 1


# 刪除不存在的域

redis> HDEL abbr not-exists-field
(integer) 0


# 刪除多個域

redis> HDEL abbr b c
(integer) 2

redis> HGETALL abbr
1) "d"
2) "dog"
複製程式碼
  1. HMSET key field value [field value ...]
    時間複雜度O(N)Nfield-value對的數量。
    同時將多個field-value(域-值)對設定到雜湊表key中,此命令會覆蓋雜湊表中已存在的域,如果key不存在,一個空雜湊表被建立並執行HMSET操作。
    返回值: 如果命令執行成功,返回OK,當key不是雜湊表(hash)型別時,返回一個錯誤。 程式碼演示:
redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HGET website google
"www.google.com"

redis> HGET website yahoo
"www.yahoo.com"
複製程式碼
  1. HMGET key field [field ...]
    時間複雜度O(N)N為給定域的數量。
    返回雜湊表key中,一個或多個給定域的值,如果給定的域不存在於雜湊表,那麼返回一個nil值,因為不存在的key被當作一個空雜湊表來處理,所以對一個不存在的key進行HMGET操作將返回一個只帶有nil值的表。
    返回值: 一個包含多個給定域的關聯值的表,表值的排列順序和給定域引數的請求順序一樣。
    程式碼演示:
redis> HMSET pet dog "doudou" cat "nounou"    # 一次設定多個域
OK

redis> HMGET pet dog cat fake_pet             # 返回值的順序和傳入引數的順序一樣
1) "doudou"
2) "nounou"
3) (nil)                                      # 不存在的域返回nil值
複製程式碼
  1. N次HGET和一次HMGET對比
    參考字串的NGET和一次MGET對比,大概相同

列表

列表用於儲存多個有序的字串,列表是一種比較靈活的資料結構,可以充當佇列的角色。

鍵值結構

列表的value其實是一個雙向連結串列,可以在連結串列的兩頭插入或者刪除元素

image

命令

  1. LPUSH key value [value ...]
    時間複雜度O(1)
    將一個或多個值value插入到列表key的表頭,如果有多個value值,那麼各個value值按從左到右的順序依次插入到表頭:比如說,對空列表mylist執行命令LPUSH mylist a b c,列表的值將是c b a,這等同於原子性地執行LPUSH mylist aLPUSH mylist bLPUSH mylist c三個命令,如果key不存在,一個空列表會被建立並執行LPUSH操作,當key存在但不是列表型別時,返回一個錯誤。
    返回值: 執行LPUSH命令後,列表的長度。 程式碼演示:
# 加入單個元素

redis> LPUSH languages python
(integer) 1


# 加入重複元素

redis> LPUSH languages python
(integer) 2

redis> LRANGE languages 0 -1     # 列表允許重複元素
1) "python"
2) "python"


# 加入多個元素

redis> LPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"
複製程式碼
  1. RPUSH key value [value ...]
    時間複雜度O(1)
    將一個或多個值value插入到列表key的表尾(最右邊),如果有多個value值,那麼各個value值按從左到右的順序依次插入到表尾:比如說,對空列表mylist執行命令RPUSH mylist a b c,列表的值將是c b a,這等同於原子性地執行RPUSH mylist aRPUSH mylist bRPUSH mylist c三個命令,如果key不存在,一個空列表會被建立並執行RPUSH操作,當key存在但不是列表型別時,返回一個錯誤。
    返回值: 執行RPUSH命令後,列表的長度。 程式碼演示:
# 新增單個元素

redis> RPUSH languages c
(integer) 1


# 新增重複元素

redis> RPUSH languages c
(integer) 2

redis> LRANGE languages 0 -1 # 列表允許重複元素
1) "c"
2) "c"


# 新增多個元素

redis> RPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"
複製程式碼
  1. LPOP key
    時間複雜度O(1)
    移除頭元素並返回列表key新的頭元素。
    返回值: 列表的頭元素。當key不存在時,返回nil程式碼演示:
# 加入單個元素
redis> LLEN course
(integer) 0

redis> RPUSH course algorithm001
(integer) 1

redis> RPUSH course c++101
(integer) 2

redis> LPOP course  # 移除頭元素
"algorithm001"
複製程式碼
  1. RPOP key
    時間複雜度O(1)
    移除尾元素並返回列表key新的尾元素。
    返回值: 列表的尾元素。當key不存在時,返回nil程式碼演示:
redis> RPUSH mylist "one"
(integer) 1

redis> RPUSH mylist "two"
(integer) 2

redis> RPUSH mylist "three"
(integer) 3

redis> RPOP mylist           # 返回被彈出的元素
"three"

redis> LRANGE mylist 0 -1    # 列表剩下的元素
1) "one"
2) "two"
複製程式碼
  1. LINDEX key index
    時間複雜度O(N)N為到達下標index過程中經過的元素數量。因此,對列表的頭元素和尾元素執行LINDEX命令,複雜度為O(1)。
    返回列表key中,下標為index的元素,下標(index)引數startstop都以0為底,也就是說,以0表示列表的第一個元素,以1表示列表的第二個元素,以此類推,你也可以使用負數下標,以-1表示列表的最後一個元素,-2表示列表的倒數第二個元素,以此類推,如果key不是列表型別,返回一個錯誤。
    返回值: 列表中下標為index的元素。如果index引數的值不在列表的區間範圍內(out of range),返回nil
    程式碼演示:
redis> LPUSH mylist "World"
(integer) 1

redis> LPUSH mylist "Hello"
(integer) 2

redis> LINDEX mylist 0
"Hello"

redis> LINDEX mylist -1
"World"

redis> LINDEX mylist 3        # index不在 mylist 的區間範圍內
(nil)
複製程式碼
  1. LINSERT key BEFORE|AFTER pivot value
    時間複雜度O(N)N為尋找pivot過程中經過的元素數量。
    將值value插入到列表key當中,位於值pivot之前或之後,當pivot不存在於列表key時,不執行任何操作,當key不存在時,key被視為空列表,不執行任何操作,如果key不是列表型別,返回一個錯誤。
    返回值: 如果命令執行成功,返回插入操作完成之後,列表的長度。如果沒有找到pivot,返回-1。如果key不存在或為空列表,返回0
    程式碼演示:
redis> RPUSH mylist "Hello"
(integer) 1

redis> RPUSH mylist "World"
(integer) 2

redis> LINSERT mylist BEFORE "World" "There"
(integer) 3

redis> LRANGE mylist 0 -1
1) "Hello"
2) "There"
3) "World"


# 對一個非空列表插入,查詢一個不存在的 pivot

redis> LINSERT mylist BEFORE "go" "let's"
(integer) -1                                    # 失敗


# 對一個空列表執行 LINSERT 命令

redis> EXISTS fake_list
(integer) 0

redis> LINSERT fake_list BEFORE "nono" "gogogog"
(integer) 0                                      # 失敗
複製程式碼

集合

Redis的SetString型別的無序集合,這裡的集合也就是我們小學都接觸到的集合,可以求交集、並集、差集等。集合成員是唯一的,這就意味著集合中不能出現重複的資料。集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。

鍵值結構

左邊為key,是字串型別。右邊為value,可以將一些字串進行一些組合,是集合型別。Redis中的集合型別還支援集合之間的操作,這與Redis中的其他資料結構是不同的,Redis可以對兩個集合進行操作,取兩個集合的交集,並集,差集以及對稱差集等。

image

命令

  1. SADD key member [member …]
    時間複雜度O(N)N為被新增的元素的數量。
    將一個或多個member元素加入到集合key當中,已經存在於集合的member元素將被忽略,假如key不存在,則建立一個只包含member元素作成員的集合,當key不是集合型別時,返回一個錯誤。
    返回值: 被新增到集合中的新元素的數量,不包括被忽略的元素。
    程式碼演示:
# 新增單個元素

redis> SADD bbs "discuz.net"
(integer) 1


# 新增重複元素

redis> SADD bbs "discuz.net"
(integer) 0


# 新增多個元素

redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2

redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"
複製程式碼
  1. SPOP key [count]
    時間複雜度O(1)
    隨機移除count個元素並返回被移除的元素。
    返回值: 被移除的隨機元素。當key不存在或key是空集時,返回nil
    程式碼演示:
redis> SMEMBERS db
1) "MySQL"
2) "MongoDB"
3) "Redis"

redis> SPOP db
"Redis"

redis> SMEMBERS db
1) "MySQL"
2) "MongoDB"

redis> SPOP db
"MySQL"

redis> SMEMBERS db
1) "MongoDB"
複製程式碼
  1. SREM key member [member …]
    時間複雜度O(N)N為給定member元素的個數。
    移除集合key中的一個或多個member元素,不存在的member元素會被忽略,當key不是集合型別,返回一個錯誤。
    返回值: 被成功移除的元素的個數,不包括被忽略的元素。
    程式碼演示:
# 測試資料

redis> SMEMBERS languages
1) "c"
2) "lisp"
3) "python"
4) "ruby"


# 移除單個元素

redis> SREM languages ruby
(integer) 1


# 移除不存在元素

redis> SREM languages non-exists-language
(integer) 0


# 移除多個元素

redis> SREM languages lisp python c
(integer) 3

redis> SMEMBERS languages
(empty list or set)
複製程式碼
  1. SMEMBERS key
    時間複雜度O(N)N為集合的基數。
    返回集合key中的所有成員,不存在的key被視為空集合。
    返回值: 集合中的所有成員。
    程式碼演示:
# key 不存在或集合為空

redis> EXISTS not_exists_key
(integer) 0

redis> SMEMBERS not_exists_key
(empty list or set)


# 非空集合

redis> SADD language Ruby Python Clojure
(integer) 3

redis> SMEMBERS language
1) "Python"
2) "Ruby"
3) "Clojure"
複製程式碼

有序集合

Redis有序集合和集合一樣也是String型別元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double型別的分數。Redis正是通過分數來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。

鍵值結構

有序集合的value包括scorevalue兩部分,其中score表示分值用來排序的

image

命令

  1. ZADD key [NX|XX] [CH] [INCR] score member [score member …]
    時間複雜度O(M*log(N))N是有序集的基數,M為成功新增的新成員的數量。
    將一個或多個member元素及其score值加入到有序集key當中。如果某個member已經是有序集的成員,那麼更新這個memberscore值,並通過重新插入這個member元素,來保證該member在正確的位置上。score值可以是整數值或雙精度浮點數。如果key不存在,則建立一個空的有序集並執行ZADD操作。當key存在但不是有序集型別時,返回一個錯誤。
    Redis 3.0.2 為ZADD命令新增了NXXXCHINCR 四個選項:
  • NXmember必須不存在,才可以設定成功,用於新增。
  • XXmember必須存在,才可以設定成功,用於更新。
  • CH:返回此次操作後,有序集合元素和分數發生變化的個數。
  • INCR:對score做增加,相當於ZINCRBY返回值: 被成功新增的新成員的數量,不包括那些被更新的、已經存在的成員。
    程式碼演示:
 redis> ZADD ztest 100 java 99 python 80 go 120 kotlin
(integer) 4
# 檢視有序集合內所有元素並且按分數排序
 coderknock> ZRANGE ztest 0 -1 WITHSCORES
1) "go"
2) "80"
3) "python"
4) "99"
5) "java"
6) "100"
7) "kotlin"
8) "120"
# 選項填寫在 key 後面,位置不能錯誤
 redis> ZADD ztest 100 java 99 python 80 go 120 kotlin CH
(error) ERR syntax error
 redis> ZADD CH ztest 100 java 99 python 80 go 120 kotlin
(error) ERR syntax error
# 下面兩個語句進行了對比,如果不加 CH 顯示的數量不包括更新和已經存在的。
 redis>  ZADD ztest CH 100 java 99 python 80 go 121 kotlin
(integer) 1
 redis>  ZADD ztest 100 java 99 python 80 go 120 kotlin
(integer) 0
複製程式碼
  1. ZREM key member [member …]
    時間複雜度O(M*log(N))N是有序集的基數,M為成功移除的成員的數量。
    移除有序集key中的一個或多個成員,不存在的成員將被忽略,當key存在但不是有序集型別時,返回一個錯誤。
    返回值: 被成功移除的成員的數量,不包括被忽略的成員。
    程式碼演示:
# 測試資料

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 移除單個元素

redis> ZREM page_rank google.com
(integer) 1

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"


# 移除多個元素

redis> ZREM page_rank baidu.com bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
(empty list or set)


# 移除不存在元素

redis> ZREM page_rank non-exists-element
(integer) 0
複製程式碼

相關文章