Redis 集合對(duì)象

2018-08-02 14:49 更新

集合對(duì)象的編碼可以是 intset 或者 hashtable 。

intset 編碼的集合對(duì)象使用整數(shù)集合作為底層實(shí)現(xiàn), 集合對(duì)象包含的所有元素都被保存在整數(shù)集合里面。

舉個(gè)例子, 以下代碼將創(chuàng)建一個(gè)如圖 8-12 所示的 intset 編碼集合對(duì)象:

redis> SADD numbers 1 3 5
(integer) 3

另一方面, hashtable 編碼的集合對(duì)象使用字典作為底層實(shí)現(xiàn), 字典的每個(gè)鍵都是一個(gè)字符串對(duì)象, 每個(gè)字符串對(duì)象包含了一個(gè)集合元素, 而字典的值則全部被設(shè)置為 NULL 。

舉個(gè)例子, 以下代碼將創(chuàng)建一個(gè)如圖 8-13 所示的 hashtable 編碼集合對(duì)象:

redis> SADD fruits "apple" "banana" "cherry"
(integer) 3

編碼的轉(zhuǎn)換

當(dāng)集合對(duì)象可以同時(shí)滿足以下兩個(gè)條件時(shí), 對(duì)象使用 intset 編碼:

  1. 集合對(duì)象保存的所有元素都是整數(shù)值;
  2. 集合對(duì)象保存的元素?cái)?shù)量不超過 512 個(gè);

不能滿足這兩個(gè)條件的集合對(duì)象需要使用 hashtable 編碼。

注意

第二個(gè)條件的上限值是可以修改的, 具體請(qǐng)看配置文件中關(guān)于 set-max-intset-entries 選項(xiàng)的說明。

對(duì)于使用 intset 編碼的集合對(duì)象來說, 當(dāng)使用 intset 編碼所需的兩個(gè)條件的任意一個(gè)不能被滿足時(shí), 對(duì)象的編碼轉(zhuǎn)換操作就會(huì)被執(zhí)行: 原本保存在整數(shù)集合中的所有元素都會(huì)被轉(zhuǎn)移并保存到字典里面, 并且對(duì)象的編碼也會(huì)從 intset 變?yōu)?nbsp;hashtable 。

舉個(gè)例子, 以下代碼創(chuàng)建了一個(gè)只包含整數(shù)元素的集合對(duì)象, 該對(duì)象的編碼為 intset :

redis> SADD numbers 1 3 5
(integer) 3

redis> OBJECT ENCODING numbers
"intset"

不過, 只要我們向這個(gè)只包含整數(shù)元素的集合對(duì)象添加一個(gè)字符串元素, 集合對(duì)象的編碼轉(zhuǎn)移操作就會(huì)被執(zhí)行:

redis> SADD numbers "seven"
(integer) 1

redis> OBJECT ENCODING numbers
"hashtable"

除此之外, 如果我們創(chuàng)建一個(gè)包含 512 個(gè)整數(shù)元素的集合對(duì)象, 那么對(duì)象的編碼應(yīng)該會(huì)是 intset :

redis> EVAL "for i=1, 512 do redis.call('SADD', KEYS[1], i) end" 1 integers
(nil)

redis> SCARD integers
(integer) 512

redis> OBJECT ENCODING integers
"intset"

但是, 只要我們?cè)傧蚣咸砑右粋€(gè)新的整數(shù)元素, 使得這個(gè)集合的元素?cái)?shù)量變成 513 , 那么對(duì)象的編碼轉(zhuǎn)換操作就會(huì)被執(zhí)行:

redis> SADD integers 10086
(integer) 1

redis> SCARD integers
(integer) 513

redis> OBJECT ENCODING integers
"hashtable"

集合命令的實(shí)現(xiàn)

因?yàn)榧湘I的值為集合對(duì)象, 所以用于集合鍵的所有命令都是針對(duì)集合對(duì)象來構(gòu)建的, 表 8-10 列出了其中一部分集合鍵命令, 以及這些命令在不同編碼的集合對(duì)象下的實(shí)現(xiàn)方法。


表 8-10 集合命令的實(shí)現(xiàn)方法

命令 intset 編碼的實(shí)現(xiàn)方法 hashtable 編碼的實(shí)現(xiàn)方法
SADD 調(diào)用 intsetAdd 函數(shù), 將所有新元素添加到整數(shù)集合里面。 調(diào)用 dictAdd , 以新元素為鍵, NULL 為值, 將鍵值對(duì)添加到字典里面。
SCARD 調(diào)用 intsetLen 函數(shù), 返回整數(shù)集合所包含的元素?cái)?shù)量, 這個(gè)數(shù)量就是集合對(duì)象所包含的元素?cái)?shù)量。 調(diào)用 dictSize 函數(shù), 返回字典所包含的鍵值對(duì)數(shù)量, 這個(gè)數(shù)量就是集合對(duì)象所包含的元素?cái)?shù)量。
SISMEMBER 調(diào)用 intsetFind 函數(shù), 在整數(shù)集合中查找給定的元素, 如果找到了說明元素存在于集合, 沒找到則說明元素不存在于集合。 調(diào)用 dictFind 函數(shù), 在字典的鍵中查找給定的元素, 如果找到了說明元素存在于集合, 沒找到則說明元素不存在于集合。
SMEMBERS 遍歷整個(gè)整數(shù)集合, 使用 intsetGet 函數(shù)返回集合元素。 遍歷整個(gè)字典, 使用 dictGetKey 函數(shù)返回字典的鍵作為集合元素。
SRANDMEMBER 調(diào)用 intsetRandom 函數(shù), 從整數(shù)集合中隨機(jī)返回一個(gè)元素。 調(diào)用 dictGetRandomKey 函數(shù), 從字典中隨機(jī)返回一個(gè)字典鍵。
SPOP 調(diào)用 intsetRandom 函數(shù), 從整數(shù)集合中隨機(jī)取出一個(gè)元素, 在將這個(gè)隨機(jī)元素返回給客戶端之后, 調(diào)用 intsetRemove 函數(shù), 將隨機(jī)元素從整數(shù)集合中刪除掉。 調(diào)用 dictGetRandomKey 函數(shù), 從字典中隨機(jī)取出一個(gè)字典鍵, 在將這個(gè)隨機(jī)字典鍵的值返回給客戶端之后, 調(diào)用dictDelete 函數(shù), 從字典中刪除隨機(jī)字典鍵所對(duì)應(yīng)的鍵值對(duì)。
SREM 調(diào)用 intsetRemove 函數(shù), 從整數(shù)集合中刪除所有給定的元素。 調(diào)用 dictDelete 函數(shù), 從字典中刪除所有鍵為給定元素的鍵值對(duì)。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)