Redis教程:數據對象分析(一)

目錄

1 五種基本數據對象

2 數據結構對象分析

 2.1 類型

2.2 編碼與底層實現

2.3 編碼轉換


1 五種基本數據對象

圖1 redis數據對象

2 數據結構對象分析

      Redis中的每個對象都由一個redisObject結構表示,該結構中保存數據相關的三個屬性分別是:type、encoding、ptr。

redis.h

typedef struct redisObject {
    //類型
    unsigned type:4;
    unsigned notused:2; 
    //編碼
    unsigned encoding:4;
    unsigned lru:22; 
    //引用計數
    int refcount;
    //指向底層實現數據結構的指針
    void *ptr;
} robj;

 2.1 類型

      對象的type屬性記錄了對象的類型,這個屬性的值可以是表2-1列出對的常量中的一個。

表2-1 不同類型值對象的TYPE命令輸出
對象 對象type屬性的值 TYPE命令的輸出
字符串對象 REDIS_STRING string
列表對象 REDIS_LIST list
哈希對象 REDIS_HASH hash
集合對象 REDIS_SET set
有序集合對象 REDIS_ZSET zset

      TYPE命令的實現方式也與此類似,當我們對一個數據庫鍵執行TYPE命令時,命令返回的結果爲數據庫鍵對應的值對象類型,而不是鍵對象類型:

# 鍵爲字符串對象,值爲字符串對象
127.0.0.1:6379> SET msg "hello world"
OK
127.0.0.1:6379> TYPE msg
string
# 鍵爲字符串對象,值爲列表對象
127.0.0.1:6379> RPUSH numbers 1 3 5
(integer) 3
127.0.0.1:6379> TYPE numbers
list
# 鍵爲字符串對象,值爲哈希對象
127.0.0.1:6379> HMSET profile name Tome age 25 career Programmer
OK
127.0.0.1:6379> TYPE profile
hash
# 鍵爲字符串對象,值爲集合對象
127.0.0.1:6379> SADD fruits apple banana cherry
(integer) 3
127.0.0.1:6379> TYPE fruits
set
# 鍵爲字符串對象,值爲有序集合對象
127.0.0.1:6379> ZADD price 8.5 apple 5.0 banana 6.0 cherry
(integer) 3
127.0.0.1:6379> TYPE price
zset

2.2 編碼與底層實現

      對象的ptr指針指向對象的底層實現數據結構,而這些數據結構由對象的encoding屬性決定。encoding屬性記錄了對象使用的編碼,也即是說這個對象使用了什麼數據結構作爲對象的底層實現,這個屬性的值可以是表2-2列出的常量的其中一個。

表2-2 OBJECT ENCODING對不同編碼的輸出
對象所使用的底層數據結構 編碼常量 OBJECT ENCODING命令輸出
整數 REDIS_ENCODING_INT int
embstr編碼的簡單動態字符串(SDS) REDIS_ENCODING_EMBSTR embstr
簡單動態字符串 REDIS_ENCODING_RAW raw
字典 REDIS_ENCODING_HT hashtable
雙端鏈表 REDIS_ENCODING_LINKEDLIST linkedlist
壓縮列表 REDIS_ENCODING_ZIPLIST ziplist
整數集合 REDIS_ENCODING_INTSET intset
跳躍表和字典 REDIS_ENCODING_SKIPLIST skiplist

使用OBJECT ENCODING命令可以查看一個數據庫鍵的值對象的編碼:

127.0.0.1:6379> SET msg "hello wrold"
OK
127.0.0.1:6379> OBJECT ENCODING msg
"embstr"
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"

每種類型的對象都至少使用了兩種不同的編碼,表2-3列出了每種類型的對象可以使用的編碼:

表2-3 不同類型和編碼的對象
類型 編碼 對象
REDIS_STRING REDIS_ENCODING_INT 使用整數值實現的字符串對象
REDIS_STRING REDIS_ENCODING_EMBSTR 使用embstr編碼的簡單動態字符串實現的字符串對象
REDIS_STRING REDIS_ENCODING_RAW 使用簡單動態字符串實現的字符串對象
REDIS_LIST REDIS_ENCODING_ZIPLIST 使用壓縮列表實現的列表對象
REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用雙端鏈表實現的列表對象
REDIS_HASH REDIS_ENCODING_ZIPLIST 使用壓縮列表實現的哈希對象
REDIS_HASH REDIS_ENCODING_HT 使用字典實現的哈希對象
REDIS_SET REDIS_ENCODING_INTSET 使用整數集合實現的集合對象
REDIS_SET REDIS_ENCODING_HT 使用字典實現的集合對象
REDIS_ZSET REDIS_ENCODING_ZIPLIST 使用壓縮列表實現的有序集合對象
REDIS_ZSET REDIS_ENCODING_SKIPLIST 使用跳躍表和字典實現的有序集合對象

2.3 編碼轉換

(1)字符串對象

  • 對於int編碼的字符串對象來說,如果我們向對象執行了一些命令,使得對象保存的不再是整數值,而是一個字符串值,那麼字符串對象將從int變爲raw。
  • 對embstr編碼的字符串對象執行任何修改命令時,程序先將對象的編碼從embstr轉換成raw,然後再執行修改命令。

(2)列表對象

當列表對象可以同時滿足以下兩個條件時,列表對象使用ziplist編碼:

  • 列表對象保存的所有字符串元素的長度都小於64字節
  • 列表對象保存的元素數量小於512個

(3)哈希對象

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

  • 哈希對象保存的所有鍵值對的鍵和值的字符串長度都小於64字節
  • 哈希對象保存的鍵值對數量小於512個

(4)集合對象

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

  • 集合對象保存的所有元素都是整數值
  • 集合對象保存的元素數量不超過512個

(5)有序集合

當有序集合對象可以同時滿足以下條件時,對象使用ziplist編碼:

  • 有序集合保存的元素數量小於128個
  • 有序集合保存的所有元素的長度小於64字節

 

參考:

1、redis設計與實現(第二版)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章