Redis的数据结构

Redis初始给了我们16个库,数据都是以键---值对来存储的,其中键的数据结构固定为string,值的数据类型有五种分别为:string、list、set、hash、zset。

1.string(字符串)

string是最简单常用的数据结构,不同的类型有不同的编码格式:

  • 整数类型,字符串对象的编码格式为int。
  • 短字符串长度<=44,字符串对象的编码格式为embstr。
  • 长字符串长度>44,字符串对象的编码格式为raw。

最常用的就是计数器,比如文章点赞量、访问量等等。

2.list (列表)

list是可重复的列表,是按插入的顺序排序的,实现方式有两种分别是ziplist和quicklist。

2.1ziplist实现list

在list中元素数量较少的情况下采用的是压缩链表ziplist存储,ziplist内存占用的是一块连续空间利用数组实现 ,可以存字符串整数 ,其内部有ziplist**占用字节的总数、元素的总个数、首尾的偏移量。**首尾的偏移量用来快速定位到最后一个元素,可用于从后往前遍历。

2.2quicklist实现list

quick是一个双向链表,是基于ziplist实现的,其内部的每一个结点都是ziplist,用于list元素数量大于512时存储。

list主要被用于像展现粉丝列表、关注列表等等。

3.set(集合)

set是无序不可重复 ,无序只是表明不保证按插入顺序存储,实现方式有两种分别是inset和hashtable。

3.1inset实现set

inset内部也是一块连续的内存空间,利用数组来实现,用于集合中元素数量较少的情况,而且只能存储整数,为的是节约内存而提高效率,如果有非整数内部的实现就会立刻变为hashtable结构。

3.2hashtable实现set

如果元素数量大于512个,使用hashtable来存储,实现set集合只使用了hashtable中的键,值为null,可以快速查询到需要的数据。

set可用做存储商品的标签,后续用于并、交、差操作。

4.hash(散列)

redis中的散列可以存储多个键值对,实现方式有ziplist和hashtable。

4.1ziplist实现hash

可以使用两个ziplist来实现hash,一个存储键(field),另一个存储值(vlaue),用于键值对中的字符串长度小于64并且元素数量较少的情况。

4.2hashtable实现hash

当键值对的字符串长度大于64或者元素数量大于512时,使用hashtable来实现即可。

hash可用做存储用户购买的商品、购物车,比如用户的id为key,然后商品的id为field,购买商品的数量为value。

5.zset

zset是排好序(默认由大到小)的集合,和散列一样,只不过value存储的是score分数,是按照分数来排序的,有序集合的实现方式有ziplist和skiplist(跳表)。

5.1ziplist实现zset

元素数量小于128并且键值小于64字节 时可以使用两个紧挨的ziplist来实现zset,元素有序是因为当新增一个元素时,需要扩大内存以及从前到后一个个进行元素比对最终找到合适的插入位置 ,其中会涉及到元素的移动,最坏情况下如果扩大内存时,后面的内存不是空闲的,这就会涉及到整个ziplist的数据重新迁移。

5.2skiplist实现zset

跳表是在压缩列表的基础上增加了多级索引,其寻址的过程为:从最高层开始开始查找,如果当前位置的next指针为null,那么就下降到下一层,如果next指向的元素小于查找的值,那么就继续向后去遍历查找,如果大于查找的值,那么就调用backward后退指针指向next位置的前一个元素,向前去比较寻找即可。如下图二级索引示例查找27:

至于为什么不使用平衡二叉树来实现zset的一部分原因是因为其每个节点都需要指向左右子树的2个指针 ,而使用skiplist平均每个元素需要1.3个指针,我们都知道局限redis的会是内存空间大小和网络速度,所以使用skiplist会更加的节省内存空间。

zset最主要的使用场景就是排行榜。

相关推荐
DemonAvenger3 小时前
NoSQL与MySQL混合架构设计:从入门到实战的最佳实践
数据库·mysql·性能优化
AAA修煤气灶刘哥14 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥14 小时前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
RestCloud18 小时前
揭秘 CDC 技术:让数据库同步快人一步
数据库·api
得物技术21 小时前
MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术
数据库·后端·mysql
christine-rr1 天前
linux常用命令(4)——压缩命令
linux·服务器·redis
可涵不会debug1 天前
【IoTDB】时序数据库选型指南:工业大数据场景下的技术突围
数据库·时序数据库
ByteBlossom1 天前
MySQL 面试场景题之如何处理 BLOB 和CLOB 数据类型?
数据库·mysql·面试
麦兜*1 天前
MongoDB Atlas 云数据库实战:从零搭建全球多节点集群
java·数据库·spring boot·mongodb·spring·spring cloud
Slaughter信仰1 天前
深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第十章知识点问答(10题)
java·jvm·数据库