简介:redis并没有直接使用前面所提到的基本数据结构,而是基于基本的数据结构构造了一个对象系统。这个系统包含了字符串对象,列表对象,哈希对象,集合对象,有序集合对象五种类型的对象。每种对象都用到了至少一种我们前面所说的数据结构。
redis使用对象来表示数据库中的键和值,每次当我们在redis数据库中创建一个键值对的时候,我们至少会创建两个对象。
redis中的每个对象都由一个redisObject结构表示:
对象有以下几种类型:
对于redis数据库来说,键总是一个字符串对象,值可能是上述五种对象的其中一种。地方
Type命令在面对不同类型对象时所产生的输出如下:
encodeing属性决定了ptr指针指向的底层数据结构的数据结构类型也称为对象编码。
每种类型的对象至少对应了两种不同的编码,下面列出每种对象可以使用的编码。
使用object encoding命令可以查看一个数据库的值对象的编码
下表展示了不同编码对象对应的object encoding命令的输出
通过encoding属性去设置对象的编码方式,极大地提高了redis存储对象的底层数据结构的灵活性,因为不同的数据结构适用的存储场景不一样,比如列表对象包含的元素比较少的时候,redis采用压缩列表作为存储的数据结构。当元素逐渐增多到某个值的时候又会变为双端链表作为存储的数据结构。
这是因为压缩列表比双端链表更节约内存,而且在元素数量较少时,在内存中以连续块方式保存的压缩列表比双端链表更容易载入到缓存。
字符串对象的编码可以是int,emstr,raw。
int保存的整数值对象,emstr保存的是小于32字节等于32字节的对象,raw保存的是大于32字节的对象。
emstr和raw的区别在于raw会调用两次内存分配函数分别创建redisObject结构和sdshdr结构,而embstr编码只会调用一次内存分配函数来分配一个连续的内存空间,空间中一次包含了redisObject和sdshdr两个结构。如下图所示:
使用emstr编码的字符串有以下的优势:
1》在创建和释放字符串对象时都只用对内存进行一次操作。
2》保存在一个内存块中的对象更容易被加载到缓存。
long和double类型的浮点数也是作为字符串保存的
1.编码的转换
int编码和emstr编码的字符串在条件满足的情况下可以转变为raw编码的字符串
比如上述代码中类型为int的10086append一个字符串,将会使最终结果的类型变为raw类型。
对于emstr类型的字符串只要执行了修改的命令就会将emstr类型转换为raw类型 。
列表对象的编码可以是ziplist或者是linkedlist
它们的结构如下图:
其中linkedlist对象中的字符串是一个字符串对象,如下图所示:
当列表对象同时满足以下两个条件时(不同版本的redis的定义可能不一样),列表对象将会用linkedlist实现,否则用ziplist实现。
1》列表中所有元素的占内存数小于64字节
2》列表中元素的个数小于512个
列表命令:
哈希对象的实现可以是ziplist或者是hashtable
两种方式分别如下图:
当哈希对象中的元素满足以下两个条件时,哈希对象用ziplist实现,否则用hashtable实现
1》哈希对象中的元素的占内存大小小于64字节。
2》哈希对象中的元素的个数小于512。
哈希命令:
集合对象的实现可以是intset或者hashtable
两种方式分别如下图:
当集合对象的元素满足以下两个条件时,集合对象用intset实现,否则用hashtable实现。
1》集合对象中的元素都是整数
2》集合对象中的元素的数量不超过512
集合命令:
有序集合对象有ziplist和skiplist两种实现
skiplist:
有序集合对象满足以下两个条件的时候用ziplist实现,否则用skiplist实现。
1》有序集合中元素的占内存大小小于64字节。
2》有序集合中元素的个数小于128。
有序集合命令:
原文:https://www.cnblogs.com/ll9507/p/11419253.html