W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
哈希對(duì)象的編碼可以是 ziplist
或者 hashtable
。
ziplist
編碼的哈希對(duì)象使用壓縮列表作為底層實(shí)現(xiàn), 每當(dāng)有新的鍵值對(duì)要加入到哈希對(duì)象時(shí), 程序會(huì)先將保存了鍵的壓縮列表節(jié)點(diǎn)推入到壓縮列表表尾, 然后再將保存了值的壓縮列表節(jié)點(diǎn)推入到壓縮列表表尾, 因此:
舉個(gè)例子, 如果我們執(zhí)行以下 HSET 命令, 那么服務(wù)器將創(chuàng)建一個(gè)列表對(duì)象作為 profile
鍵的值:
redis> HSET profile name "Tom"
(integer) 1
redis> HSET profile age 25
(integer) 1
redis> HSET profile career "Programmer"
(integer) 1
如果 profile
鍵的值對(duì)象使用的是 ziplist
編碼, 那么這個(gè)值對(duì)象將會(huì)是圖 8-9 所示的樣子, 其中對(duì)象所使用的壓縮列表如圖 8-10 所示。
另一方面, hashtable
編碼的哈希對(duì)象使用字典作為底層實(shí)現(xiàn), 哈希對(duì)象中的每個(gè)鍵值對(duì)都使用一個(gè)字典鍵值對(duì)來(lái)保存:
舉個(gè)例子, 如果前面 profile
鍵創(chuàng)建的不是 ziplist
編碼的哈希對(duì)象, 而是 hashtable
編碼的哈希對(duì)象, 那么這個(gè)哈希對(duì)象應(yīng)該會(huì)是圖 8-11 所示的樣子。
當(dāng)哈希對(duì)象可以同時(shí)滿足以下兩個(gè)條件時(shí), 哈希對(duì)象使用 ziplist
編碼:
64
字節(jié);512
個(gè);不能滿足這兩個(gè)條件的哈希對(duì)象需要使用 hashtable
編碼。
注意
這兩個(gè)條件的上限值是可以修改的, 具體請(qǐng)看配置文件中關(guān)于 hash-max-ziplist-value
選項(xiàng)和 hash-max-ziplist-entries
選項(xiàng)的說(shuō)明。
對(duì)于使用 ziplist
編碼的列表對(duì)象來(lái)說(shuō), 當(dāng)使用 ziplist
編碼所需的兩個(gè)條件的任意一個(gè)不能被滿足時(shí), 對(duì)象的編碼轉(zhuǎn)換操作就會(huì)被執(zhí)行: 原本保存在壓縮列表里的所有鍵值對(duì)都會(huì)被轉(zhuǎn)移并保存到字典里面, 對(duì)象的編碼也會(huì)從 ziplist
變?yōu)?nbsp;hashtable
。
以下代碼展示了哈希對(duì)象因?yàn)殒I值對(duì)的鍵長(zhǎng)度太大而引起編碼轉(zhuǎn)換的情況:
# 哈希對(duì)象只包含一個(gè)鍵和值都不超過(guò) 64 個(gè)字節(jié)的鍵值對(duì)
redis> HSET book name "Mastering C++ in 21 days"
(integer) 1
redis> OBJECT ENCODING book
"ziplist"
# 向哈希對(duì)象添加一個(gè)新的鍵值對(duì),鍵的長(zhǎng)度為 66 字節(jié)
redis> HSET book long_long_long_long_long_long_long_long_long_long_long_description "content"
(integer) 1
# 編碼已改變
redis> OBJECT ENCODING book
"hashtable"
除了鍵的長(zhǎng)度太大會(huì)引起編碼轉(zhuǎn)換之外, 值的長(zhǎng)度太大也會(huì)引起編碼轉(zhuǎn)換, 以下代碼展示了這種情況的一個(gè)示例:
# 哈希對(duì)象只包含一個(gè)鍵和值都不超過(guò) 64 個(gè)字節(jié)的鍵值對(duì)
redis> HSET blah greeting "hello world"
(integer) 1
redis> OBJECT ENCODING blah
"ziplist"
# 向哈希對(duì)象添加一個(gè)新的鍵值對(duì),值的長(zhǎng)度為 68 字節(jié)
redis> HSET blah story "many string ... many string ... many string ... many string ... many"
(integer) 1
# 編碼已改變
redis> OBJECT ENCODING blah
"hashtable"
最后, 以下代碼展示了哈希對(duì)象因?yàn)榘逆I值對(duì)數(shù)量過(guò)多而引起編碼轉(zhuǎn)換的情況:
# 創(chuàng)建一個(gè)包含 512 個(gè)鍵值對(duì)的哈希對(duì)象
redis> EVAL "for i=1, 512 do redis.call('HSET', KEYS[1], i, i) end" 1 "numbers"
(nil)
redis> HLEN numbers
(integer) 512
redis> OBJECT ENCODING numbers
"ziplist"
# 再向哈希對(duì)象添加一個(gè)新的鍵值對(duì),使得鍵值對(duì)的數(shù)量變成 513 個(gè)
redis> HMSET numbers "key" "value"
OK
redis> HLEN numbers
(integer) 513
# 編碼改變
redis> OBJECT ENCODING numbers
"hashtable"
因?yàn)楣fI的值為哈希對(duì)象, 所以用于哈希鍵的所有命令都是針對(duì)哈希對(duì)象來(lái)構(gòu)建的, 表 8-9 列出了其中一部分哈希鍵命令, 以及這些命令在不同編碼的哈希對(duì)象下的實(shí)現(xiàn)方法。
表 8-9 哈希命令的實(shí)現(xiàn)
命令 | ziplist 編碼實(shí)現(xiàn)方法 |
hashtable 編碼的實(shí)現(xiàn)方法 |
---|---|---|
HSET | 首先調(diào)用 ziplistPush 函數(shù), 將鍵推入到壓縮列表的表尾, 然后再次調(diào)用 ziplistPush 函數(shù), 將值推入到壓縮列表的表尾。 |
調(diào)用 dictAdd 函數(shù), 將新節(jié)點(diǎn)添加到字典里面。 |
HGET | 首先調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對(duì)應(yīng)的節(jié)點(diǎn), 然后調(diào)用 ziplistNext 函數(shù), 將指針移動(dòng)到鍵節(jié)點(diǎn)旁邊的值節(jié)點(diǎn), 最后返回值節(jié)點(diǎn)。 |
調(diào)用 dictFind 函數(shù), 在字典中查找給定鍵, 然后調(diào)用dictGetVal 函數(shù), 返回該鍵所對(duì)應(yīng)的值。 |
HEXISTS | 調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對(duì)應(yīng)的節(jié)點(diǎn), 如果找到的話說(shuō)明鍵值對(duì)存在, 沒(méi)找到的話就說(shuō)明鍵值對(duì)不存在。 |
調(diào)用 dictFind 函數(shù), 在字典中查找給定鍵, 如果找到的話說(shuō)明鍵值對(duì)存在, 沒(méi)找到的話就說(shuō)明鍵值對(duì)不存在。 |
HDEL | 調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對(duì)應(yīng)的節(jié)點(diǎn), 然后將相應(yīng)的鍵節(jié)點(diǎn)、 以及鍵節(jié)點(diǎn)旁邊的值節(jié)點(diǎn)都刪除掉。 |
調(diào)用 dictDelete 函數(shù), 將指定鍵所對(duì)應(yīng)的鍵值對(duì)從字典中刪除掉。 |
HLEN | 調(diào)用 ziplistLen 函數(shù), 取得壓縮列表包含節(jié)點(diǎn)的總數(shù)量, 將這個(gè)數(shù)量除以 2 , 得出的結(jié)果就是壓縮列表保存的鍵值對(duì)的數(shù)量。 |
調(diào)用 dictSize 函數(shù), 返回字典包含的鍵值對(duì)數(shù)量, 這個(gè)數(shù)量就是哈希對(duì)象包含的鍵值對(duì)數(shù)量。 |
HGETALL | 遍歷整個(gè)壓縮列表, 用 ziplistGet 函數(shù)返回所有鍵和值(都是節(jié)點(diǎn))。 |
遍歷整個(gè)字典, 用 dictGetKey 函數(shù)返回字典的鍵, 用dictGetVal 函數(shù)返回字典的值。 |
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: