W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
Redis 使用對象來表示數(shù)據(jù)庫中的鍵和值, 每次當我們在 Redis 的數(shù)據(jù)庫中新創(chuàng)建一個鍵值對時, 我們至少會創(chuàng)建兩個對象, 一個對象用作鍵值對的鍵(鍵對象), 另一個對象用作鍵值對的值(值對象)。
舉個例子, 以下 SET 命令在數(shù)據(jù)庫中創(chuàng)建了一個新的鍵值對, 其中鍵值對的鍵是一個包含了字符串值 "msg"
的對象, 而鍵值對的值則是一個包含了字符串值 "hello world"
的對象:
redis> SET msg "hello world"
OK
Redis 中的每個對象都由一個 redisObject
結構表示, 該結構中和保存數(shù)據(jù)有關的三個屬性分別是 type
屬性、 encoding
屬性和 ptr
屬性:
typedef struct redisObject {
// 類型
unsigned type:4;
// 編碼
unsigned encoding:4;
// 指向底層實現(xiàn)數(shù)據(jù)結構的指針
void *ptr;
// ...
} robj;
對象的 type
屬性記錄了對象的類型, 這個屬性的值可以是表 8-1 列出的常量的其中一個。
表 8-1 對象的類型
類型常量 | 對象的名稱 |
---|---|
REDIS_STRING |
字符串對象 |
REDIS_LIST |
列表對象 |
REDIS_HASH |
哈希對象 |
REDIS_SET |
集合對象 |
REDIS_ZSET |
有序集合對象 |
對于 Redis 數(shù)據(jù)庫保存的鍵值對來說, 鍵總是一個字符串對象, 而值則可以是字符串對象、列表對象、哈希對象、集合對象或者有序集合對象的其中一種, 因此:
諸如此類。
TYPE 命令的實現(xiàn)方式也與此類似, 當我們對一個數(shù)據(jù)庫鍵執(zhí)行 TYPE 命令時, 命令返回的結果為數(shù)據(jù)庫鍵對應的值對象的類型, 而不是鍵對象的類型:
# 鍵為字符串對象,值為字符串對象
redis> SET msg "hello world"
OK
redis> TYPE msg
string
# 鍵為字符串對象,值為列表對象
redis> RPUSH numbers 1 3 5
(integer) 6
redis> TYPE numbers
list
# 鍵為字符串對象,值為哈希對象
redis> HMSET profile name Tome age 25 career Programmer
OK
redis> TYPE profile
hash
# 鍵為字符串對象,值為集合對象
redis> SADD fruits apple banana cherry
(integer) 3
redis> TYPE fruits
set
# 鍵為字符串對象,值為有序集合對象
redis> ZADD price 8.5 apple 5.0 banana 6.0 cherry
(integer) 3
redis> TYPE price
zset
表 8-2 列出了 TYPE 命令在面對不同類型的值對象時所產生的輸出。
表 8-2 不同類型值對象的 TYPE 命令輸出
對象 | 對象 type 屬性的值 |
TYPE 命令的輸出 |
---|---|---|
字符串對象 | REDIS_STRING |
"string" |
列表對象 | REDIS_LIST |
"list" |
哈希對象 | REDIS_HASH |
"hash" |
集合對象 | REDIS_SET |
"set" |
有序集合對象 | REDIS_ZSET |
"zset" |
對象的 ptr
指針指向對象的底層實現(xiàn)數(shù)據(jù)結構, 而這些數(shù)據(jù)結構由對象的 encoding
屬性決定。
encoding
屬性記錄了對象所使用的編碼, 也即是說這個對象使用了什么數(shù)據(jù)結構作為對象的底層實現(xiàn), 這個屬性的值可以是表 8-3 列出的常量的其中一個。
表 8-3 對象的編碼
編碼常量 | 編碼所對應的底層數(shù)據(jù)結構 |
---|---|
REDIS_ENCODING_INT |
long 類型的整數(shù) |
REDIS_ENCODING_EMBSTR |
embstr 編碼的簡單動態(tài)字符串 |
REDIS_ENCODING_RAW |
簡單動態(tài)字符串 |
REDIS_ENCODING_HT |
字典 |
REDIS_ENCODING_LINKEDLIST |
雙端鏈表 |
REDIS_ENCODING_ZIPLIST |
壓縮列表 |
REDIS_ENCODING_INTSET |
整數(shù)集合 |
REDIS_ENCODING_SKIPLIST |
跳躍表和字典 |
每種類型的對象都至少使用了兩種不同的編碼, 表 8-4 列出了每種類型的對象可以使用的編碼。
表 8-4 不同類型和編碼的對象
類型 | 編碼 | 對象 |
---|---|---|
REDIS_STRING |
REDIS_ENCODING_INT |
使用整數(shù)值實現(xiàn)的字符串對象。 |
REDIS_STRING |
REDIS_ENCODING_EMBSTR |
使用 embstr 編碼的簡單動態(tài)字符串實現(xiàn)的字符串對象。 |
REDIS_STRING |
REDIS_ENCODING_RAW |
使用簡單動態(tài)字符串實現(xiàn)的字符串對象。 |
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
使用壓縮列表實現(xiàn)的列表對象。 |
REDIS_LIST |
REDIS_ENCODING_LINKEDLIST |
使用雙端鏈表實現(xiàn)的列表對象。 |
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
使用壓縮列表實現(xiàn)的哈希對象。 |
REDIS_HASH |
REDIS_ENCODING_HT |
使用字典實現(xiàn)的哈希對象。 |
REDIS_SET |
REDIS_ENCODING_INTSET |
使用整數(shù)集合實現(xiàn)的集合對象。 |
REDIS_SET |
REDIS_ENCODING_HT |
使用字典實現(xiàn)的集合對象。 |
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
使用壓縮列表實現(xiàn)的有序集合對象。 |
REDIS_ZSET |
REDIS_ENCODING_SKIPLIST |
使用跳躍表和字典實現(xiàn)的有序集合對象。 |
使用 OBJECT ENCODING 命令可以查看一個數(shù)據(jù)庫鍵的值對象的編碼:
redis> SET msg "hello wrold"
OK
redis> OBJECT ENCODING msg
"embstr"
redis> SET story "long long long long long long ago ..."
OK
redis> OBJECT ENCODING story
"raw"
redis> SADD numbers 1 3 5
(integer) 3
redis> OBJECT ENCODING numbers
"intset"
redis> SADD numbers "seven"
(integer) 1
redis> OBJECT ENCODING numbers
"hashtable"
表 8-5 列出了不同編碼的對象所對應的 OBJECT ENCODING 命令輸出。
表 8-5 OBJECT ENCODING 對不同編碼的輸出
對象所使用的底層數(shù)據(jù)結構 | 編碼常量 | OBJECT ENCODING 命令輸出 |
---|---|---|
整數(shù) | REDIS_ENCODING_INT |
"int" |
embstr 編碼的簡單動態(tài)字符串(SDS) |
REDIS_ENCODING_EMBSTR |
"embstr" |
簡單動態(tài)字符串 | REDIS_ENCODING_RAW |
"raw" |
字典 | REDIS_ENCODING_HT |
"hashtable" |
雙端鏈表 | REDIS_ENCODING_LINKEDLIST |
"linkedlist" |
壓縮列表 | REDIS_ENCODING_ZIPLIST |
"ziplist" |
整數(shù)集合 | REDIS_ENCODING_INTSET |
"intset" |
跳躍表和字典 | REDIS_ENCODING_SKIPLIST |
"skiplist" |
通過 encoding
屬性來設定對象所使用的編碼, 而不是為特定類型的對象關聯(lián)一種固定的編碼, 極大地提升了 Redis 的靈活性和效率, 因為 Redis 可以根據(jù)不同的使用場景來為一個對象設置不同的編碼, 從而優(yōu)化對象在某一場景下的效率。
舉個例子, 在列表對象包含的元素比較少時, Redis 使用壓縮列表作為列表對象的底層實現(xiàn):
其他類型的對象也會通過使用多種不同的編碼來進行類似的優(yōu)化。
在接下來的內容中, 我們將分別介紹 Redis 中的五種不同類型的對象, 說明這些對象底層所使用的編碼方式, 列出對象從一種編碼轉換成另一種編碼所需的條件, 以及同一個命令在多種不同編碼上的實現(xiàn)方法。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: