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最主要的使用场景就是排行榜。

相关推荐
机器视觉知识推荐、就业指导10 分钟前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
jnrjian16 分钟前
export rman 备份会占用buff/cache 导致内存压力
数据库·oracle
isNotNullX1 小时前
一文解读OLAP的工具和应用软件
大数据·数据库·etl
小诸葛的博客3 小时前
pg入门1——使用容器启动一个pg
数据库
大熊程序猿4 小时前
python 读取excel数据存储到mysql
数据库·python·mysql
落落落sss4 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
jnrjian4 小时前
Oracle 启动动态采样 自适应执行计划
数据库·oracle
lamb张4 小时前
MySQL锁
数据库·mysql
ForRunner1234 小时前
使用 Python 高分解决 reCAPTCHA v3 的指南
数据库·python·microsoft