16.五大类型底层

16.1 数据结构

  • SDS 动态字符串

  • 双向链表

  • 压缩列表 ziplist

  • 哈希表 hashtable

  • 跳表 skiplist

  • 整数集合 intset

  • 快速列表 quicklist

  • 紧凑列表 listpack

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


16.2 KV 键值对

  • redis 是 key-value 存储系统

    • key 一般都是 String 类型的字符串对象

    • vlaue 类型则为 redis 对象(redisObject)

    • value 可以是字符串对象,也可以是集合数据类型的对象,比如 List 对象、Hash 对象、Set 对象和 Zset 对象

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


16.2.1 10 大类型

  • 传统的 5 大类型

    • String

    • List

    • Hash

    • Set

    • ZSet

  • 新 5 大类型

    • bitmap,实质 String

    • hyperLogLog,实质 String

    • GEO,实质 Zset

    • Stream,实质 Stream

    • BITFIELD,看具体 key

16.2.2 上帝视角

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • Redis 定义了 redisObjec 结构体,来表示 string、hash、list、set、zset 等数据类型

  • redis 中每个对象都是一个 redisObject 结构

  • 字典、KV 是什么(重点)

    • 每个键值对都会有一个 dictEntry

    • 源码:dict.h

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 这些键值对是如何保存进 redis 并进行读取操作,O(1)复杂度

  • redisObject+redis 数据类型+Redis 所有编码方式(底层实现)三者之间的关系

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


16.3 底层 C 语言源码分析

16.3.1 数据结构

  1. SDS 动态字符串

  2. 双向链表

  3. 压缩列表 ziplist

  4. 哈希表 hashtable

  5. 跳表 skiplist

  6. 整数集合 intset

  7. 快速列表 quicklist

  8. 紧凑列表 listpack

  • redis6.0.5

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • redis7

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

16.3.2 经典 5 大数据结构解析

…(省略)


16.4 skiplist 跳表

16.4.1 为什么引出跳表

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个数据,也只能从头到尾遍历链表。

这样查找效率就会很低,时间复杂度会很高 O(N)

16.4.2 痛点

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解决方法:升维,也叫空间换时间。

  • 优化 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这个例子里,我们看出,加来一层索引之后,查找一个结点需要遍历的结点个数减少了,也就是说查找效率提高了。

  • 优化 2

画了一个包含 64 个结点的链表,按照前面讲的这种思路,建立了五级索引

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


16.4.3 是什么

  • 跳表是可以实现二分查找的有序链表

  • skiplist 是一种以空间换取时间的结构。

  • 由于链表,无法进行二分查找,因此借鉴数据库索引的思想,提取出链表中关键节点(索引),先在关键节点上查找,再进入下层链表查找,提取多层关键节点,就形成了跳跃表

  • 由于索引也要占据一定空间的,所以,索引添加的越多,空间占用的越多

  • 总结来讲 跳表 = 链表 + 多级索引

16.4.4 复杂度

  • 时间复杂度

    • 跳表查询的时间复杂度分析,如果链表里有 N 个结点,会有多少级索引呢?

    • 按照我们前面讲的,两两取首。每两个结点会抽出一个结点作为上一级索引的结点,以此估算:

    • 第一级索引的结点个数大约就是 n/2,

    • 第二级索引的结点个数大约就是 n/4,

    • 第三级索引的结点个数大约就是 n/8,依次类推…

    • 也就是说,第 k 级索引的结点个数是第 k-1 级索引的结点个数的 1/2,那第 k 级索引结点的个数就是 n/(2^k)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 空间复杂度

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

16.4.5 优缺点

  • 优点

    • 跳表是一个最典型的空间换时间解决方案,而且只有在数据量较大的情况下才能体现出来优势。而且是读多血少的情况下才能使用,所以他的使用范围应该还是比较有限的
  • 缺点

    • 维护成本相对要高

    • 在单链表中,一旦定位好要插入的位置,插入节点的时间复杂度是很低的,就是 O(1)

    • 但是,新增或者删除是需要把所有索引都更新一遍,为了保证原始链表中数据的有序性,我们需要先找到要动作的位置,这个查找操作就会比较耗时,最后在新增和删除的过程中的更新,时间复杂度也是 O(log n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只蜘猪

感谢!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值