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_STRINGstring
列表对象REDIS_LISTlist
哈希对象REDIS_HASHhash
集合对象REDIS_SETset
有序集合对象REDIS_ZSETzset

      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_INTint
embstr编码的简单动态字符串(SDS)REDIS_ENCODING_EMBSTRembstr
简单动态字符串REDIS_ENCODING_RAWraw
字典REDIS_ENCODING_HThashtable
双端链表REDIS_ENCODING_LINKEDLISTlinkedlist
压缩列表REDIS_ENCODING_ZIPLISTziplist
整数集合REDIS_ENCODING_INTSETintset
跳跃表和字典REDIS_ENCODING_SKIPLISTskiplist

使用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_STRINGREDIS_ENCODING_INT使用整数值实现的字符串对象
REDIS_STRINGREDIS_ENCODING_EMBSTR使用embstr编码的简单动态字符串实现的字符串对象
REDIS_STRINGREDIS_ENCODING_RAW使用简单动态字符串实现的字符串对象
REDIS_LISTREDIS_ENCODING_ZIPLIST使用压缩列表实现的列表对象
REDIS_LISTREDIS_ENCODING_LINKEDLIST使用双端链表实现的列表对象
REDIS_HASHREDIS_ENCODING_ZIPLIST使用压缩列表实现的哈希对象
REDIS_HASHREDIS_ENCODING_HT使用字典实现的哈希对象
REDIS_SETREDIS_ENCODING_INTSET使用整数集合实现的集合对象
REDIS_SETREDIS_ENCODING_HT使用字典实现的集合对象
REDIS_ZSETREDIS_ENCODING_ZIPLIST使用压缩列表实现的有序集合对象
REDIS_ZSETREDIS_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设计与实现(第二版)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值