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