W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Redis 中用于操作鍵的命令基本上可以分為兩種類型。
其中一種命令可以對任何類型的鍵執(zhí)行, 比如說 DEL 命令、 EXPIRE 命令、 RENAME 命令、 TYPE 命令、 OBJECT 命令, 等等。
舉個例子, 以下代碼就展示了使用 DEL 命令來刪除三種不同類型的鍵:
# 字符串鍵
redis> SET msg "hello"
OK
# 列表鍵
redis> RPUSH numbers 1 2 3
(integer) 3
# 集合鍵
redis> SADD fruits apple banana cherry
(integer) 3
redis> DEL msg
(integer) 1
redis> DEL numbers
(integer) 1
redis> DEL fruits
(integer) 1
而另一種命令只能對特定類型的鍵執(zhí)行, 比如說:
諸如此類。
舉個例子, 我們可以用 SET 命令創(chuàng)建一個字符串鍵, 然后用 GET 命令和 APPEND 命令操作這個鍵, 但如果我們試圖對這個字符串鍵執(zhí)行只有列表鍵才能執(zhí)行的 LLEN 命令, 那么 Redis 將向我們返回一個類型錯誤:
redis> SET msg "hello world"
OK
redis> GET msg
"hello world"
redis> APPEND msg " again!"
(integer) 18
redis> GET msg
"hello world again!"
redis> LLEN msg
(error) WRONGTYPE Operation against a key holding the wrong kind of value
從上面發(fā)生類型錯誤的代碼示例可以看出, 為了確保只有指定類型的鍵可以執(zhí)行某些特定的命令, 在執(zhí)行一個類型特定的命令之前, Redis 會先檢查輸入鍵的類型是否正確, 然后再決定是否執(zhí)行給定的命令。
類型特定命令所進行的類型檢查是通過 redisObject
結(jié)構(gòu)的 type
屬性來實現(xiàn)的:
舉個例子, 對于 LLEN 命令來說:
redisObject
結(jié)構(gòu) type
屬性的值是否為 REDIS_LIST
, 如果是的話, 服務(wù)器就對鍵執(zhí)行 LLEN 命令;圖 8-18 展示了這一類型檢查過程。
其他類型特定命令的類型檢查過程也和這里展示的 LLEN 命令的類型檢查過程類似。
Redis 除了會根據(jù)值對象的類型來判斷鍵是否能夠執(zhí)行指定命令之外, 還會根據(jù)值對象的編碼方式, 選擇正確的命令實現(xiàn)代碼來執(zhí)行命令。
舉個例子, 在前面介紹列表對象的編碼時我們說過, 列表對象有 ziplist
和 linkedlist
兩種編碼可用, 其中前者使用壓縮列表 API 來實現(xiàn)列表命令, 而后者則使用雙端鏈表 API 來實現(xiàn)列表命令。
現(xiàn)在, 考慮這樣一個情況, 如果我們對一個鍵執(zhí)行 LLEN 命令, 那么服務(wù)器除了要確保執(zhí)行命令的是列表鍵之外, 還需要根據(jù)鍵的值對象所使用的編碼來選擇正確的 LLEN 命令實現(xiàn):
ziplist
, 那么說明列表對象的實現(xiàn)為壓縮列表, 程序?qū)⑹褂?nbsp;ziplistLen
函數(shù)來返回列表的長度;linkedlist
, 那么說明列表對象的實現(xiàn)為雙端鏈表, 程序?qū)⑹褂?nbsp;listLength
函數(shù)來返回雙端鏈表的長度;借用面向?qū)ο蠓矫娴男g(shù)語來說, 我們可以認為 LLEN 命令是多態(tài)(polymorphism)的: 只要執(zhí)行 LLEN 命令的是列表鍵, 那么無論值對象使用的是 ziplist
編碼還是 linkedlist
編碼, 命令都可以正常執(zhí)行。
圖 8-19 展示了 LLEN 命令從類型檢查到根據(jù)編碼選擇實現(xiàn)函數(shù)的整個執(zhí)行過程, 其他類型特定命令的執(zhí)行過程也是類似的。
實際上, 我們可以將 DEL 、 EXPIRE 、 TYPE 等命令也稱為多態(tài)命令, 因為無論輸入的鍵是什么類型, 這些命令都可以正確地執(zhí)行。
DEL 、 EXPIRE 等命令和 LLEN 等命令的區(qū)別在于, 前者是基于類型的多態(tài) —— 一個命令可以同時用于處理多種不同類型的鍵, 而后者是基于編碼的多態(tài) —— 一個命令可以同時用于處理多種不同編碼。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: