Redis学习笔记对象(二)
redis使用对象来保存数据库的键和值,键对象与值对象,键对象总是一个字符串对象,而值对象可以是字符串对象、哈希对象、列表对象、集合对象、有序集合对象中任意一种。
对象结构:类型(type)、编码(encoding)、底层实现数据结构的指针。
type属性记录了对象的类型,在redis中由REDIS_STRING、REDIS_HASH、REDIS_LIST、REDIS_SET、REDIS_ZSET常量表示。
而encoding属性也有多种编码常量定义,实际上每种类型至少使用了两种不同的编码。
一、字符串对象(string)
当字符串对象保存的是整数值时,字符串对象的编码为int。
如果字符串对象保存的是长度大于32的字符串,那么字符串对象将使用简单动态字符串保存这个值,将编码设置为raw。当长度小于32位时采用embstr编码(此方式通过将数据保存在一块连续的内存中来提升效率),long与double类型的浮动数在redis中也是作为字符串值通过内部转换保存的。
注:实际上raw与embstr编码决定因素可能根据不同的版本而变化,本人window3.2.100版本的redis测试值为44,后续有待验证
由于embstr编码保存的字符串在redis中是只读的,所有相应修改操作会将字符串值编码转成raw编码。
二、列表对象(list)
列表对象的编码有两种,压缩列表和链表(双端链表)。
压缩列表:当列表对象保存的所有字符串元素的长度都小于64字节并且元素数量小于512个时使用压缩列表编码ziplist,否则使用双端链表编码。
当进行新增或修改操作而出现条件不满足的情况下,redis会自动进行类型转换,将压缩列表转成链表。
注:实际上较新版本中用快速列表quicklist代替了之前的压缩列表和双端链表,快速列表是一种压缩列表与链表的混合体,它将链表按段切分,每一段使用压缩列表紧凑存储,多个压缩列表使用双向指针串联起来。
三、哈希对象(hash)
哈希对象的编码可以是压缩列表或者字典。
压缩列表:当哈希对象保存的所有键值对的键和值的字符串长度都小于64字节并且键值对数量小于512个时使用压缩列表编码ziplist,否则使用hashtable字典编码(此值可通过配置文件配置)
当进行新增或修改操作而出现条件不满足的情况下,redis会自动进行类型转换,将压缩列表转成字典。
四、集合对象(set)
集合对象的编码可以是整数集合intset 或者字典。
整数集合:当集合对象所有元素值都是整数值并且所保存的元素数量少于512个时使用整数集合编码,否则转换为字典编码。
五、有序集合(zset)
有序集合编码有两种压缩列表、跳跃表
压缩列表:当有序集合对象中所有元素成员的长度都小于64字节并且保存的元素数量小于128个时使用压缩列表编码,否则自动转换为跳跃表编码skiplist。
有序集合使用压缩列表编码时每一个集合元素使用两个紧挨在一起的压缩列表节点来保存,前节点总是保存成员值,后节点保存分值。
跳跃表:当有序集合对象使用跳跃表编码时实际上对象中会同时包含一个字典和跳跃表
字典的键保存元素成员,值保存元素分值。
为什么会同时使用字典与跳跃表呢?实际上由于字典的特性,为了弥补跳跃表对于根据成员查找分值这一操作的复杂度,而跳跃表优势在于zset的有序性和范围型操作如zrank,zrange等命令。
总结:redis中这5种对象以及分别操作这几种对象的命令应该都是需要熟练掌握的。最重要的是我们在实际开发中根据业务来选择合适的数据类型。