深入理解Redis——对象

Redis 并没有直接使用上述的数据结构直接构建键值对数据库,而是是基于这些数据结构创建了一个对象系统。

Redis使用对象来表示数据库中的键和值,每次当我们在Redis的数据库中新创建一个键值对时,我们至少会创建两个对象,一个对象用作键值对的键(键对象),另一个对象用作键值对的值(值对象)。键对象总是一个字符串对象,而值对象可以是不同类型的对象。Redis中的每个对象都由一个 redisObject结构表示。

typedef struct redisObject {
		unsigned type:4; //类型
		unsigned encoding:4; //编码
		void *ptr; //指向底层实现数据结构的指针,这些数据结构由编码encoding的属性来决定
		// ...
} ;

在Redis中,每种类型的对象都至少用了两种不同的编码

 

 

字符串对象

字符串对象的编码可以是 int, embstr 和 raw

如果一个字符串对象保存的是整数值,并且这个整数值可以用 long类型来表示,字符串对象的编码设置为 int;对于可以用 long double类型表示的浮点数来说,Redis使用字符串值来保存的。

如果字符串对象保存的是一个字符串值,并且这个字符串值的长度 大于32字节,那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值,并将对象的编码设置为 raw;而当这个字符串值的长度 小于等于32字节,那么字符串对象将使用 embstr编码的方式来保存这个字符串值。

列表对象

列表对象的编码可以是 ziplist或者 linkedlist

ziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点(entry)保存了一个列表元素。

linkedlist编码的列表对象使用双端链表作为底层实现,每个双端链表节点(node)都保存了一个字符串对象,而每个字符串对象都保存了一个列表元素。

编码转换: 当列表对象可以同时满足以下两个条件时,列表对象使用ziplist编码:

  • 列表对象保存的所有字符串元素的长度都小于64字节;
  • 列表对象保存的元素数量小于512个;不能满足这两个条件的列表对象需要使用linkedlist编码。

哈希对象

哈希对象的编码可以是 ziplist或者 hashtable

ziplist编码的哈希对象使用 **ziplist**作为底层实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了的压缩列表节点推入到压缩列表表尾,然后再将保存了的压缩列表节点推入到压缩列表表尾。

hashtable编码的哈希对象使用 **字典**作为底层实现,哈希对象中的每个键值对都使用一个字典键值对来保存。

编码转换:

当哈希对象可以同时满足以下两个条件时,哈希对象使用ziplist编码:

  • 哈希对象保存的所有键值对的键和值的字符串长度都小于64字节.
  • 哈希对象保存的键值对数量小于512个;不能满足这两个条件的哈希对象需要使用hashtable编码。

集合对象

集合对象的编码可以是 intset或者 hashtable

intset编码的集合对象使用 **整数集合**作为底层实现,集合对象包含的所有元素都被保存在整数集合里面。

hashtable编码的集合对象使用 字典作为底层实现,字典的key都是一个字符串对象,每个字符串对象包含了一个集合元素,而字典的value则全部被设置为 NULL

编码转换:

当集合对象可以同时满足以下两个条件时,对象使用intset编码:

  • 集合对象保存的所有元素都是整数值;
  • 集合对象保存的元素数量不超过512个。

有序集合对象

有序集合的编码可以是 ziplist或者 skiplist

ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),而第二个元素则保存元素的分值(score),压缩列表内的集合元素按分值从小到大进行排序。

skiplist编码的有序集合对象使用 zset结构作为底层实现,一个 zset结构同时包含一个字典和一个跳跃表:

struct zset{
		zskiplist *zsl;
		dict *dict;
}zset;

zset结构中的 zsl跳跃表按分值从小到大保存了所有集合元素,每个跳跃表节点都保存了一个集合元素。zset结构中的dict字典为有序集合创建了一个从成员到分值(score)的映射,字典中的每个键值对都保存了一个集合元素,通过这个字典,程序可以用 O(1)复杂度查找给定成员的分值, ZSCORE命令就是根据这一特性实现的。

为了让有序集合的查找和范围型操作都尽可能快地执行,Redis选择了同时使用字典和跳跃表两种数据结构来实现有序集合。

编码转换:

当有序集合对象可以同时满足以下两个条件时,对象使用 ziplist编码:

  • 有序集合保存的元素数量小于128个;
  • 有序集合保存的所有元素成员的长度都小于64字节;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值