三、Redis中数据结构的对象
再次看回这张图,觉不觉得就很好理解了?
数据结构对应的类型与编码
3.1字符串(stirng)对象
在上面的图我们知道string类型有三种编码格式:
- int:整数值,这个整数值可以使用long类型来表示
- 如果是浮点数,那就用embstr或者raw编码。具体用哪个就看这个数的长度了
- embstr:字符串值,这个字符串值的长度小于32字节
- raw:字符串值,这个字符串值的长度大于32字节
embstr和raw的区别:
- raw分配内存和释放内存的次数是两次,embstr是一次
- embstr编码的数据保存在一块连续的内存里面
编码之间的转换:
- int类型如果存的不再是一个整数值,则会从int转成raw
- embstr是只读的,在修改的时候回从embstr转成raw
3.2列表(list)对象
在上面的图我们知道list类型有两种编码格式:
- ziplist:字符串元素的长度都小于64个字节
&&
总数量少于512个 - linkedlist:字符串元素的长度大于64个字节
||
总数量大于512个
ziplist编码的列表结构:
redis > RPUSH numbers 1 "three" 5 (integer) 3
ziplist的列表结构
linkedlist编码的列表结构:
linkedlist编码的列表结构
编码之间的转换:
- 原本是ziplist编码的,如果保存的数据长度太大或者元素数量过多,会转换成linkedlist编码的。
3.3哈希(hash)对象
在上面的图我们知道hash类型有两种编码格式:
- ziplist:key和value的字符串长度都小于64字节
&&
键值对总数量小于512 - hashtable:key和value的字符串长度大于64字节
||
键值对总数量大于512
ziplist编码的哈希结构:
ziplist编码的哈希结构1
ziplist编码的哈希结构2
hashtable编码的哈希结构:
hashtable编码的哈希结构
编码之间的转换:
- 原本是ziplist编码的,如果保存的数据长度太大或者元素数量过多,会转换成hashtable编码的。
3.4集合(set)对象
在上面的图我们知道set类型有两种编码格式:
- intset:保存的元素全都是整数
&&
总数量小于512 - hashtable:保存的元素不是整数
||
总数量大于512
intset编码的集合结构:
intset编码的集合结构
hashtable编码的集合结构:
hashtable编码的集合结构
编码之间的转换:
- 原本是intset编码的,如果保存的数据不是整数值或者元素数量大于512,会转换成hashtable编码的。
3.5有序集合(sortset)对象
在上面的图我们知道set类型有两种编码格式:
- ziplist:元素长度小于64
&&
总数量小于128 - skiplist:元素长度大于64
||
总数量大于128
ziplist编码的有序集合结构:
ziplist编码的有序集合结构1
ziplist编码的有序集合结构2
skiplist编码的有序集合结构:
skiplist编码的有序集合结构
有序集合(sortset)对象同时采用skiplist和哈希表来实现:
- skiplist能够达到插入的时间复杂度为O(logn),根据成员查分值的时间复杂度为O(1)
编码之间的转换:
- 原本是ziplist编码的,如果保存的数据长度大于64或者元素数量大于128,会转换成skiplist编码的。
3.6Redis对象一些细节
- (1:服务器在执行某些命令的时候,会先检查给定的键的类型能否执行指定的命令。
- 比如我们的数据结构是sortset,但你使用了list的命令。这是不对的,服务器会检查一下我们的数据结构是什么才会进一步执行命令
- (2:Redis的对象系统带有引用计数实现的内存回收机制。
- 对象不再被使用的时候,对象所占用的内存会释放掉
- (3:Redis会共享值为0到9999的字符串对象
- (4:对象会记录自己的最后一次被访问时间,这个时间可以用于计算对象的空转时间。
最后
本文主要讲了一下Redis常用的数据结构,以及这些数据结构的底层设计是怎么样的。整体来说不会太难,因为这些数据结构我们在学习的过程中多多少少都接触过了,《Redis设计与实现》这本书写得也足够通俗易懂。
至于我们在使用的时候挑选哪些数据结构作为存储,可以简单看看:
- string-->简单的
key-value
- list-->有序列表(底层是双向链表)-->可做简单队列
- set-->无序列表(去重)-->提供一系列的交集、并集、差集的命令
- hash-->哈希表-->存储结构化数据
- sortset-->有序集合映射(member-score)-->排行榜
如果大家有更好的理解方式或者文章有错误的地方还请大家不吝在评论区留言,大家互相学习交流~~~