1. 程式人生 > 實用技巧 >Redis閱讀筆記-集合物件

Redis閱讀筆記-集合物件

Redis閱讀筆記-集合物件

​ 集合物件的編碼可以是intset或hashtable。

​ intset編碼的集合物件使用整數集合作為底層實現, 集合物件包含的所有元素都被儲存再整數集合裡。

​ 舉個例子, 以下程式碼將建立如下所示的intset編碼集合物件:

127.0.0.1:6379> sadd numbers 1 3 5
(integer) 3
redisObject
type
REDIS_SET
encoding
REDIS_ENCODING_INTSET
ptr intset
... encoding
INTSET_ENC_INT16
length
3
contents 1 3 5

​ 另一方面, hashtable編碼的集合物件使用字典作為底層實現, 字典的每個鍵都是一個字串物件, 每個字串物件包含了一個集合元素,而字典的值全部被設定為NULL。

​ 舉個例子, 以下程式碼將建立如下圖所示的hashtable編碼集合物件:

127.0.0.1:6379> sadd fruits "apple" "banana" "cherry"
(integer) 3
redisObject
type
REDIS_SET
encoding
REDIS_ENCODING_HT
ptr dict
... StringObject
"cherry"
NULL
StringObject
"apple"
NULL
StringObject
"banana"
NULL

編碼的轉換

​ 當集合物件可以同時滿足以下兩個條件時, 物件使用intset編碼:

  • 集合物件儲存的所有元素都是整數值;
  • 集合物件儲存的元素資料不超過512個

​ 不能滿足這兩個條件的集合物件需要使用hashtable編碼。

注意

​ 這兩個條件的上限值是可以修改的,具體請看配置檔案中關於set-max-intset-entries選項的說明。

​ 對於使用intset編碼的集合物件來說, 當使用intset編碼所需的兩個條件的任意一個不能被滿足時, 就會執行物件的編碼轉換操作,原本儲存再整數集合中的所有元素都會被轉移並儲存到字典裡, 並且物件的編碼也會從intset變為hashtable。

​ 舉個例子,以下程式碼建立了一個只包含整數元素的集合物件, 該物件的編碼為intset:

127.0.0.1:6379> sadd numbers 1 3 5
(integer) 3
127.0.0.1:6379> object encoding numbers
"intset"

​ 不過,只要我們向這個只包含整數元素的集合物件新增一個字串元素, 集合物件的編碼轉移操作就會被執行:

127.0.0.1:6379> sadd numbers "seven"
(integer) 1
127.0.0.1:6379> object encoding numbers
"hashtable"

​ 除此之外, 若我們建立一個包含了512個整數元素的集合物件, 那麼物件的編碼應該時intset:

127.0.0.1:6379> eval "for i=1, 512 do redis.call('SADD', KEYS[1], i) end" 1 integers
(nil)
127.0.0.1:6379> scard integers
(integer) 512
127.0.0.1:6379> object encoding integers
"intset"

​ 但是,只要再向集合新增一個新的整數元素, 使得這個結合的元素變成513, 那麼物件的編碼轉換操作就會被執行:

127.0.0.1:6379> sadd integers 10086
(integer) 1
127.0.0.1:6379> scard integers
(integer) 513
127.0.0.1:6379> object encoding integers
"hashtable"