Redis命令介紹之鍵值對操作

前文已經提及過Redis中對於鍵值對操作的一些命令,如DELEXPIRE / PEXPIRETTL / PTTL以及EXISTS。今天我們繼續介紹Redis中對鍵值對操作的相關命令。

TYPE

TYPE命令用於獲取指定鍵值對的類型,返回的值有stringlistsetzsethash以及stream。當鍵值對不存在時返回none

TYPE key

示例

redis> SET key1 "value"
OK
redis> LPUSH key2 "value"
(integer) 1
redis> SADD key3 "value"
(integer) 1
redis> TYPE key1
string
redis> TYPE key2
list
redis> TYPE key3
set
redis> TYPE key4
none

RENAME / RENAMENX

RENAME命令用於將指定鍵名重命名,並在鍵值對不存在時返回一個錯誤。若新的鍵名已存在,將會覆蓋舊值(無論舊值是否和新值是同一類型)。當Redis版本小於等於3.2.0時,若新鍵名與舊鍵名相同將返回錯誤。

RENAME key newkey

若原鍵key有關聯過期時間,則無論新鍵是否關聯有過期時間,都將被覆蓋。

當新鍵名已經存在時,執行RENAME命令時會先隱式地調用DEL操作刪除對應的鍵值對,再執行重命名的操作。

RENAMENX命令與RENAME相似,二者的區別爲RENAMENX僅在新鍵名不存在的情況下才完成重命名的操作。若新鍵名newkey已存在將會返回0,否則在正確完成重命名操作後返回0。同樣,當原鍵名不存在時將返回錯誤。

RENAMENX key newkey

示例

redis> SET greeting "hello"
OK
redis> RENAME greeting my-greeting
OK
redis> EXISTS greeting
(integer) 0
redis> EXISTS my-greeting
(integer) 1
redis> RENAME greeting new-greeting
(error) ERR no such key

當鍵名key1key2都且類型不同時,使用RENAME也將覆蓋key2的值:

redis> SET key1 "value1"
OK
redis> LPUSH key2 "value2"
(integer) 1
redis> RENAME key1 key2
OK
redis> TYPE key2
string

使用RENAME重命名關聯過期時間的鍵:

# 新鍵繼承原鍵的過期時間
redis> SET key1 EX 100
OK
redis> RENAME key1 key2
OK
redis> TTL key2
(integer) 98
# 新鍵原先的過期時間被覆蓋
redis> SET key3 EX 300
OK
redis> RENAME key2 key3
OK
redis> TTL key3
(integer) 92

使用RENAMENX命令:

redis> SET key1 "value"
OK
redis> RENAMENX key1 key2
(integer) 1
# 新鍵名key3已存在的情況下
redis> SET key3 "value"
OK
redis> RENAMENX key2 key3
(integer) 0

PERSIST

PERSIST命令用於移除指定鍵的過期時間。

PERSIST key

示例

redis> SET greeting "hello"
OK
redis> EXPIRE greeting 100
(integer) 1
redis> TTL greeting
(integer) 98
redis> PERSIST greeting
(integer) 1
redis> TTL greeting
(integer) -1
# 未關聯過期時間的鍵
redis> PERSIST greeting
(integer) 0

EXPIREAT / PEXPIREAT

EXPIREAT命令與之前介紹過的EXPIREPEXPIRE命令類似,用於設置已存在的鍵值對的過期時間。與前兩個命令不同的是,EXPIREATPEXPIREAT接受的參數是以秒爲單位的Unix時間戳。當過期時間被成功設置,該命令將返回1,反之返回0

EXPIREAT key timestamp

EXPIRE相同,若指定的過期時間戳早於當前時間,該鍵將被刪除。

PEXPIREATEXPIREAT相同,它通過傳遞的以毫秒爲單位的Unix時間戳設置過期的時間。

EXPIREAT key milliseconds-timestamp

示例

# 假設當前時間爲1577836800 (2020-01-01T00:00:00)
redis> SET greeting "hello"
OK
# 2020-01-01T00:01:40
redis> EXPIREAT greeting 1577836900
(integer) 1
redis> TTL greeting
(integer) 99
# 早於當前時間的時間戳1577836700 (2019-12-31T23:58:20)
redis> EXPIREAT greeting 1577836700
(integer) 1
redis> EXISTS greeting
(integer) 0

通過PEXPIREAT設置毫秒爲單位的過期時間:

# 毫秒爲單位的時間戳1577836900000 (2020-01-01T00:01:40)
redis> PEXPIREAT greeting 1577836900000
(integer) 1
redis> PTTL greeting
(integer) 98805
redis> TTL greeting
(integer) 98

KEYS

KEYS用於獲取所有符合給定模式(pattern)要求的鍵。

KEYS pattern

由於KEYS會掃描當前數據庫中所有的鍵值對,在生產環境中應當儘量避免使用該命令。如果需要相應的功能,可以使用下面將介紹的SCAN命令替代,或者另外使用set保存可能需要訪問的鍵名。

KEYS命令支持glob-style的模式,包括有:

  • ?代表匹配任意單個字符,例如h?llo匹配hellohallo等;
  • *代表匹配0個或多個任意字符,例如h*llo匹配hellohllllllo等;
  • [characters]匹配一個方括號內的字符,例如h[ae]llo匹配hello以及hallo
  • [^character]匹配一個非括號內^符號後的字符,例如h[^e]llo匹配hallohbllo等,但不匹配hello
  • [character-character]匹配一個方括號內兩個字符範圍內的所有字符,例如h[a-e]llo匹配hallohbllohcllohdllo以及hello

若模式內需要保護以上提到的?*[]^-字符,可以使用\進行轉義。

示例

redis> MSET firstname John lastname Doe age 25
OK
redis> KEYS *name*
1) "firstname"
2) "lastname"
redis> KEYS a??
1) "age"
redis> KEYS *
1) "firstname"
2) "lastname"
3) "age"

SCAN

SCAN命令用於增量式迭代元素集合,與其相似的還有SSCANHSCAN以及ZSCANSCAN用於迭代當前數據庫中的所有鍵,其它幾個分別是對集合、哈希、有序集合類型進行迭代,我們將在後續的文章中對其它幾個命令進行介紹。

增量迭代的命令每次執行只會返回少數結果,不同於KEYS命令返回所有的結果(可能導致服務阻塞)。但是使用增量式迭代的過程中可能會發現鍵被修改的情況,它只能對返回的結果提供有限的保證。

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

SCAN命令是一個基於遊標cursor的迭代器,每次執行後將會返回一個新的遊標,以作爲下一輪迭代的遊標參數。一次的迭代以遊標0爲開始,並在返回遊標0時結束,稱之爲一次完整的迭代。若在迭代的途中使用了錯誤的遊標,命令執行的結果將不能保證正確,但不會對服務器本身造成影響。

SCAN命令將會返回一個包含兩個值的數組,數組的第一個值爲下一輪迭代的新遊標,第二個元素爲一個數組,其中包含本輪迭代遍歷到的元素。

對於SCAN命令,以及上面提到的SCAN族中的其它命令,只能在完整迭代下提供保證對於完整遍歷開始至結束期間都存在的所有元素,必然在某次迭代中被返回;而對於在完整迭代中不存在的元素(如迭代開始前被刪除或迭代結束後被添加的元素),必然不會被返回。

在一次完整的迭代中,一個元素可能會被多次返回,需要客戶端自己處理重複的情況。在迭代中若存在元素並非一直存在(中途添加或刪除),則不能確定是否會被返回,這是一個未定義的行爲。增量迭代的算法只能保證數據集在有界的情況下停止,若在迭代的途中不斷添加新的數據,迭代可能將用於不會結束。

SCAN命令不能保證每次迭代返回的元素數量,返回0個元素也是被允許的,只要是返回的遊標不爲0迭代都仍未結束。對於一個較大的數據集,每次迭代可能會返回數十個元素;而對於一個較小的數據集,一次迭代可能會返回全部的元素。另外,可以通過COUNT參數設置每次迭代返回元素的最大值。

Redis可同時正確處理來自多個客戶端的迭代請求,迭代中的遊標記錄包含了迭代的所有狀態,服務器無須另外記錄迭代的狀態。同時,客戶端也可在任意時刻停止迭代,且不會對服務器造成影響。

可選參數

  • MATCH 提供與KEYS相同的模式匹配行爲,執行後將只返回符合模式的鍵。
  • COUNT 用於設置迭代返回元素數量的最大值,默認值爲10。通常每次迭代獲取的元素數量達到指定值時將結束,但COUNT參數僅是一個作爲提示(hint)的值。
    • 當遍歷一個足夠大的數據集時且未使用MATCH選項時,返回的結果可能略大於指定的值。
    • 當遍歷一個整數集合或編碼爲壓縮列表(ziplist),將會在第一次迭代就返回所有元素。
  • TYPE Redis 6.0中新加的參數,使迭代時只遍歷指定類型的鍵。其參數允許的值爲stringlistsetzsethash以及stream,即TYPE命令可能返回的所有類型。TYPE參數只可被用於SCAN命令。

示例

# 設置了15個鍵,鍵名爲key1至key15
# 以0作爲遊標
# 命令返回遊標7以及包含本次被迭代的元素
redis> SCAN 0
1) "7"
2)  1) "key13"
    2) "key5"
    3) "key11"
    4) "key6"
    5) "key9"
    6) "key12"
    7) "key3"
    8) "key4"
    9) "key10"
   10) "key2"
   11) "key1"
   12) "key7"
# 以遊標7作爲第二次迭代的新遊標
# 命令返回0,表示迭代結束
redis> SCAN 7
1) "0"
2) 1) "key15"
   2) "key14"
   3) "key8"

噹噹前數據庫爲空時使用SCAN命令:

redis> SCAN 0
1) "0"
2) (empty array)

使用MATCH參數:

redis> MSET firstname John lastname Doe age 25
OK
redis> SCAN 0 MATCH *name*
1) "0"
2)  1) "firstname"
    2) "lastname"

RANDOMKEY

RANDOMKEY命令用於隨機取出一個存在的鍵。若當前數據庫中不存在任何鍵,則返回nil

RANDOMKEY

示例

redis> RANDOMKEY
(nil)
redis> MSET key1 "value1" key2 "value2" key3 "value3" key4 "value4" key5 "value5"
OK
redis> RANDOMKEY
"key5"
redis> RANDOMKEY
"key1"

UNLINK

UNLINK命令與DEL命令相似,它被用於刪除指定鍵名中存在的鍵,並忽略不存在的鍵。此命令與DEL命令的區別是,它在另一個線程中執行刪除的操作。其執行刪除操作時會先將需要刪除的鍵從鍵空間中移除,再異步地釋放資源。UNLINK命令是非阻塞的刪除操作,而DEL命令是阻塞的刪除操作,在一些較複雜的情況下可採用UNLINK命令避免Redis阻塞(在6.0版本前Redis是單線程處理的)。

UNLINK key [key ...]

UNLINK命令與DEL命令相同,都將返回刪除鍵的個數。

示例

redis> SET key1 "value1"
OK
redis> SET key2 "value2"
OK
redis> UNLINK key1 key2 key3
(integer) 2

結束語

本文中介紹了Redis中對鍵進行操作的相關命令,對於Redis文檔中Keys類別下的諸如DUMPMOVEOBJECT等命令,將會在後續介紹Redis的遷移、服務、調試等相關命令時會提及,本文中便暫時不深入介紹。

歡迎大家關注我的公衆號“風紙”,或是掃下面的二維碼關注👇
風紙

參考文獻

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章