99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Redis 哈希對象

2018-08-02 14:48 更新

哈希對象的編碼可以是 ziplist 或者 hashtable 。

ziplist 編碼的哈希對象使用壓縮列表作為底層實現(xiàn), 每當(dāng)有新的鍵值對要加入到哈希對象時, 程序會先將保存了鍵的壓縮列表節(jié)點推入到壓縮列表表尾, 然后再將保存了值的壓縮列表節(jié)點推入到壓縮列表表尾, 因此:

  • 保存了同一鍵值對的兩個節(jié)點總是緊挨在一起, 保存鍵的節(jié)點在前, 保存值的節(jié)點在后;
  • 先添加到哈希對象中的鍵值對會被放在壓縮列表的表頭方向, 而后來添加到哈希對象中的鍵值對會被放在壓縮列表的表尾方向。

舉個例子, 如果我們執(zhí)行以下 HSET 命令, 那么服務(wù)器將創(chuàng)建一個列表對象作為 profile 鍵的值:

redis> HSET profile name "Tom"
(integer) 1

redis> HSET profile age 25
(integer) 1

redis> HSET profile career "Programmer"
(integer) 1

如果 profile 鍵的值對象使用的是 ziplist 編碼, 那么這個值對象將會是圖 8-9 所示的樣子, 其中對象所使用的壓縮列表如圖 8-10 所示。

另一方面, hashtable 編碼的哈希對象使用字典作為底層實現(xiàn), 哈希對象中的每個鍵值對都使用一個字典鍵值對來保存:

  • 字典的每個鍵都是一個字符串對象, 對象中保存了鍵值對的鍵;
  • 字典的每個值都是一個字符串對象, 對象中保存了鍵值對的值。

舉個例子, 如果前面 profile 鍵創(chuàng)建的不是 ziplist 編碼的哈希對象, 而是 hashtable 編碼的哈希對象, 那么這個哈希對象應(yīng)該會是圖 8-11 所示的樣子。

編碼轉(zhuǎn)換

當(dāng)哈希對象可以同時滿足以下兩個條件時, 哈希對象使用 ziplist 編碼:

  1. 哈希對象保存的所有鍵值對的鍵和值的字符串長度都小于 64 字節(jié);
  2. 哈希對象保存的鍵值對數(shù)量小于 512 個;

不能滿足這兩個條件的哈希對象需要使用 hashtable 編碼。

注意

這兩個條件的上限值是可以修改的, 具體請看配置文件中關(guān)于 hash-max-ziplist-value 選項和 hash-max-ziplist-entries 選項的說明。

對于使用 ziplist 編碼的列表對象來說, 當(dāng)使用 ziplist 編碼所需的兩個條件的任意一個不能被滿足時, 對象的編碼轉(zhuǎn)換操作就會被執(zhí)行: 原本保存在壓縮列表里的所有鍵值對都會被轉(zhuǎn)移并保存到字典里面, 對象的編碼也會從 ziplist 變?yōu)?nbsp;hashtable 。

以下代碼展示了哈希對象因為鍵值對的鍵長度太大而引起編碼轉(zhuǎn)換的情況:

# 哈希對象只包含一個鍵和值都不超過 64 個字節(jié)的鍵值對
redis> HSET book name "Mastering C++ in 21 days"
(integer) 1

redis> OBJECT ENCODING book
"ziplist"

# 向哈希對象添加一個新的鍵值對,鍵的長度為 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"

除了鍵的長度太大會引起編碼轉(zhuǎn)換之外, 值的長度太大也會引起編碼轉(zhuǎn)換, 以下代碼展示了這種情況的一個示例:

# 哈希對象只包含一個鍵和值都不超過 64 個字節(jié)的鍵值對
redis> HSET blah greeting "hello world"
(integer) 1

redis> OBJECT ENCODING blah
"ziplist"

# 向哈希對象添加一個新的鍵值對,值的長度為 68 字節(jié)
redis> HSET blah story "many string ... many string ... many string ... many string ... many"
(integer) 1

# 編碼已改變
redis> OBJECT ENCODING blah
"hashtable"

最后, 以下代碼展示了哈希對象因為包含的鍵值對數(shù)量過多而引起編碼轉(zhuǎn)換的情況:

# 創(chuàng)建一個包含 512 個鍵值對的哈希對象
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"

# 再向哈希對象添加一個新的鍵值對,使得鍵值對的數(shù)量變成 513 個
redis> HMSET numbers "key" "value"
OK

redis> HLEN numbers
(integer) 513

# 編碼改變
redis> OBJECT ENCODING numbers
"hashtable"

哈希命令的實現(xiàn)

因為哈希鍵的值為哈希對象, 所以用于哈希鍵的所有命令都是針對哈希對象來構(gòu)建的, 表 8-9 列出了其中一部分哈希鍵命令, 以及這些命令在不同編碼的哈希對象下的實現(xiàn)方法。


表 8-9 哈希命令的實現(xiàn)

命令 ziplist 編碼實現(xiàn)方法 hashtable 編碼的實現(xiàn)方法
HSET 首先調(diào)用 ziplistPush 函數(shù), 將鍵推入到壓縮列表的表尾, 然后再次調(diào)用 ziplistPush 函數(shù), 將值推入到壓縮列表的表尾。 調(diào)用 dictAdd 函數(shù), 將新節(jié)點添加到字典里面。
HGET 首先調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對應(yīng)的節(jié)點, 然后調(diào)用 ziplistNext 函數(shù), 將指針移動到鍵節(jié)點旁邊的值節(jié)點, 最后返回值節(jié)點。 調(diào)用 dictFind 函數(shù), 在字典中查找給定鍵, 然后調(diào)用dictGetVal 函數(shù), 返回該鍵所對應(yīng)的值。
HEXISTS 調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對應(yīng)的節(jié)點, 如果找到的話說明鍵值對存在, 沒找到的話就說明鍵值對不存在。 調(diào)用 dictFind 函數(shù), 在字典中查找給定鍵, 如果找到的話說明鍵值對存在, 沒找到的話就說明鍵值對不存在。
HDEL 調(diào)用 ziplistFind 函數(shù), 在壓縮列表中查找指定鍵所對應(yīng)的節(jié)點, 然后將相應(yīng)的鍵節(jié)點、 以及鍵節(jié)點旁邊的值節(jié)點都刪除掉。 調(diào)用 dictDelete 函數(shù), 將指定鍵所對應(yīng)的鍵值對從字典中刪除掉。
HLEN 調(diào)用 ziplistLen 函數(shù), 取得壓縮列表包含節(jié)點的總數(shù)量, 將這個數(shù)量除以 2 , 得出的結(jié)果就是壓縮列表保存的鍵值對的數(shù)量。 調(diào)用 dictSize 函數(shù), 返回字典包含的鍵值對數(shù)量, 這個數(shù)量就是哈希對象包含的鍵值對數(shù)量。
HGETALL 遍歷整個壓縮列表, 用 ziplistGet 函數(shù)返回所有鍵和值(都是節(jié)點)。 遍歷整個字典, 用 dictGetKey 函數(shù)返回字典的鍵, 用dictGetVal 函數(shù)返回字典的值。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號