redis基础数据结构和编码方式

一、基础数据结构

1)简单动态字符串

2)双端链表

3)字典

4)跳跃表

5)整数集合

6)压缩列表

二、对象类型与编码

  在redis的数据库中创建一个新的键值对时,总是创建两个对象,一个存储键,一个存储值。

对象的数据结构如下

typedef struct redisObject{

  unsigned typed:4;

  ungigned encoding:4;

  void *ptr;

}robj;

类型常量对应的对象名称

  1)REDIS_String:  字符串对象

  2)REDIS_LIST:    列表对象

  3)REDIS_HASH: 哈希对象

  4)REDIS_SET:    集合对象

  5)REDIS_ZSET: 有序集合对象

编码和底层实现

  1)REDIS_ENCODING_INT:       long类型的整数

  2)REDIS_ENCODING_EMBSTR:    简单动态字符串

  3)REDIS_ENCODING_RAW:      简单动态字符串

  4)  REDIS_ENCODING_HT:       字典

  5)REDIS_ENCODING_LINGKEDLIST:  双端链表

  6)REDIS_ENCODING_ZIPLIST:     压缩列表

  7)REDIS_ENCODING_INTSET:     整数集合

  8)REDIS_ENCONDING_SKIPLIST :   跳跃表和字典

三、 字符串对象

1、字符串的编码:

字符串对象的编码可以是int、raw或者embstr。

  1)如果一个字符串对象保存的是整数值,并且这个整数值可以用lon类型表示,那么字符串对象将整数值保存在字符串对象结构的ptr属性里面(将void*转换成long),并将字符串对象的编码方式设置为int。

  2)如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节,那么字符串对象将使用一个简单动态字符串保存这个值,并将对象的编码设置为raw。

  3)如果字符串对象保存的是一个字符串值,并且这个字符串值的长度小于32字节,那么字符串对象将使用embstr编码的方式来保存这个字符串值。

2、编码的转换

  int编码和embstr编码的字符串对象在满足条件的情况下,会转换为raw编码的字符串对象。

  1)int编码转为raw编码:原对象保存的值不再是整数值,而是一个字符串值,那么会发生编码从int变为raw

  2)redis没有为embstr编码的字符串对象编写任何相应的修改程序(只有int转为raw),所以,embstr编码字符串实际上是只读的,当对embstr编码的字符从执行修改命令时,

  程序会先将对象的embstr转换成raw,然后再执行修改命令。(embstr编码的字符串对象执行APPEND命令后,对象的编码会从embstr变为raw)。

四、列表对象

1、列表对象的编码:

  列表对象的编码可以是ziplist或者linkedlistziplist编码的列表对象使用压缩列表作为底层实现,每个压缩列表节点保存一个列表节点。linkedlist编码的列表对象使用双端链表作为底层

实现。每个双端链表节点(node)都保存一个字符串对象,而每个字符串对象都保存了一个列表元素。

2、编码的转换

当列表对象可以同时满足一下两个条件时,列表对象使用ziplist编码,不能满足这两个条件的列表对象需要使用linkedlist编码。

  1)列表对象保存的所有字符串元素的长度都小于64字节

  2)列表对象保存的元素数量小于512个,

五、哈希对象

1、哈希对象的编码:

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

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

  1. 保存了同一键值对的两个节点总是紧挨在一起,保存键的节点在前,保存值的节点在后;
  2. 先添加到哈希对象中的键值对会放在压缩列表的表头方向,而后添加的哈希对象中的键指对会被放在压缩列表的链表方向。

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

  1. 字典的每个键都是一个字符串对象,对象中保存了键值对的键。
  2. 字典中每个值都是一个字符串对象,对象中保存了键值对的值。

2、编码的转换

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

  1)哈希对象保存的所有键值对的键和值的字符串长度都小于64个字节

  2)哈希对象保存的键值对数量小于512个。

六、集合对象

1、集合对象的编码:

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

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

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

2、编码的转换

  同时满足两个条件使用intset,否则使用hashtable

  1)集合对象保存的所有值都是整数值

  2)集合对象保存的元素数量不超过512个

七、有序集合对象

1、有序集合对象的编码:

  有序集合对象的编码可以时ziplist或者skiplist

  1)ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member),第二个元素保存元素的分值(score)

  压缩列表内的集合元素按照分值从小到大进行排序,分值较小的元素被放置在靠近表头的方向,而分值较大的元素则放置在靠近表尾的方向。

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

  1. zset结构中的zsl跳跃表按分值从小到大保存了所有集合元素,每个跳跃表节点都保存一个集合元素:跳跃表即诶单的object属性保存了元素成员,而跳跃表节点的score属性则保存了元素的分值。

  通过跳跃表,程序可以对有序集合进行范围型操作,比如ZRANK、ZRANGE等命令就是基于跳跃表API来实现的

   2. zset结构中的dict字典为有序集合创建了一个从成员到分值的映射,字典中的每个键值对都保存了一个集合元素:字典的键保存了元素的成员,而字典的值则保存了元素的分值。通过字典,程序

  可以用O(1)复杂度查找给定成员的分值,ZSCORE命令就是根据这一特性是实现的。

2、编码的转换

  同时满足一下两个条件使用ziplist,否则使用skiplist

  1)有序集合所保存的所有元素成员的长度都小于64字节

  2)有序集合保存的元素数量小于128个

参考:《redis设计与实现》

字符串对象将使用一个简单动态字符串保存这个值,并将对象的编码设置为raw。

redis基础数据结构及编码方式的更多相关文章

  1. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

  2. 1.基础: 万丈高楼平地起——Redis基础数据结构 学习记录

    <Redis深度历险:核心原理和应用实践>1.基础: 万丈高楼平地起——Redis基础数据结构 学习记录http://naotu.baidu.com/file/b874e2624d3f37 ...

  3. 浅析Redis基础数据结构

    Redis是一种内存数据库,所以可以很方便的直接基于内存中的数据结构,对外提供众多的接口,而这些接口实际上就是对不同的数据结构进行操作的算法,首先redis本身是一种key-value的数据库,对于v ...

  4. Redis 基础数据结构与对象

    Redis用到的底层数据结构有:简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等,Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包 ...

  5. Redis基础数据结构

    Redis数据库中每个键值对都是由对象( c 的结构体对象)组成的. 数据库键总是一个字符串对象(string object) 数据库键的值可以使字符串对象.列表对象(list object).哈希对 ...

  6. Redis 基础数据结构之二 list(列表)

    Redis 有 5 种基础数据结构,分别为:string (字符串).list (列表).set (集合).hash (哈希) 和 zset (有序集合). 今天来说一下list(列表)这种数据结构, ...

  7. Redis——基础数据结构

    Redis提供了5种基础数据结构,分别是String,list,set,hash和zset. 1.String Redis所有的键都是String.Redis的String是动态字符串,内部结构类似J ...

  8. Redis 基础数据结构之一:string(字符串)

    Redis 有 5 种基础数据结构,分别为:string (字符串).list (列表).set (集合).hash (哈希) 和 zset (有序集合),Redis存储数据的结构是键值对形式的. 首 ...

  9. day6 基础总结和编码方式

    # = 赋值 == 比较值是否相等 is 比较内存地址 li1 = [1, 2, 3] li2 = li1 print(li1 is li2) print(id(li1), id(li2)) #数字, ...

随机推荐

  1. C++基础面试题及答案

    C++ C++ 和C的主要区别 C语言是面向过程编程,C++是面向对象编程,C++ 完全兼容C C++有哪些特性,简述对他们的理解 封装.继承.多态 封装 将的事物抽象成一个个集合(也就是所说的类), ...

  2. CSS漂亮盒子(下)

    4.多重背景 CSS支持一个元素设置多个背景图片. 每个背景属性有相应的多值语法,多个值由逗号分隔. .multi-bg-shorthand { width: 300px; height: 200px ...

  3. Eclipse开发Android项目报错解决方案详细教程,最新版一篇就够了!

    本文记录刚接触Android开发搭建环境后新建工程各种可能的报错,并亲身经历漫长的解决过程(╥╯^╰╥),寻找各种偏方,避免大家采坑,希望能帮助到大家. 报错信息 出错一:The import and ...

  4. 冷饭新炒:理解Snowflake算法的实现原理

    前提 Snowflake(雪花)是Twitter开源的高性能ID生成算法(服务). 上图是Snowflake的Github仓库,master分支中的REAEMDE文件中提示:初始版本于2010年发布, ...

  5. 制作 macOS Sierra U盘USB启动安装盘方法教程 (亲测)

    备注:相关镜像到apple官网下载 https://discussionschinese.apple.com/thread/250596904 进去点击"请使用这个 App Store 链接 ...

  6. SpringMVC4——视图、视图解析器、国际化

    视图.视图解析器.国际化 视图的顶级接口:View 视图解析器:ViewResolver   常见的视图和解析器: InternalResourceView.InternalResourceViewR ...

  7. Android Studio 突然无法识别真机问题

    最近在赶项目,今天AS突然疯狂跟我作对,森气!! 平时连接手机没有问题,今天突然各种识别不到真机!! 1.数据线,check.没有问题. 2.重启AS,还是不行. 3.安装驱动,行不通. 4.已经弹出 ...

  8. css实现网页缩放时固定定位的盒子与版心一同缩放

    在网页设计过程中我们可能会出现这种情况:设置好一个固定定位的盒子,但是当网页缩放时固定定位的盒子与网页的版心分离 这是因为css定位中的固定定位是以页面为参照进行定位的,而不是以版心盒子为参照,那么我 ...

  9. 从零开始讲解JavaScript中作用域链的概念及用途

    从零开始讲解JavaScript中作用域链的概念及用途 引言 正文 一.执行环境 二.作用域链 三.块级作用域 四.其他情况 五.总结 结束语 引言 先点赞,再看博客,顺手可以点个关注. 微信公众号搜 ...

  10. JavaScript学习系列博客_32_JavaScript 包装类

    包装类 - 在JS中为我们提供了三个包装类: String() Boolean() Number() - 通过这三个包装类可以创建基本数据类型的对象 例子: var num = new Number( ...