Redis 数据类型和各自的使用场景

Redis 数据类型和各自的使用场景

常见的有五种数据类型:String字符串,List列表,Hash哈希,Set集合、Zset有序集合。

1、String类型

String适用场景:一般用于缓存字符串对象

它底层的数据结构是 SDS简单动态字符串。

1、SDS 不仅可以保存文本数据,而且能保存图片、视频、压缩文件这样的二进制数据。

2、SDS 获取字符串长度的效率更高,用 len 属性记录了字符串长度,时间复杂度大约是 O(1)。而C 语言的字符串没有len, O(n);

3、Redis 的 SDS API 是安全的,拼接字符串不会造成缓冲区溢出,因为拼接之前会先检查,如果空间不够就自动扩容。

2、List类型

List场景:一般用于任务队列

底层数据结构由 quicklist 快表实现。

Quicklist :「双链表 + 压缩列表」组合,一个 quicklist 就是一个链表,而链表中的每个元素是一个压缩列表。

压缩列表:是一块连续的内存空间,有点像数组。但是它有一个记录前一个元素长度的字段,主要是帮助快速定位到列表中的下一个元素,从而提高遍历效率。但是有【连锁更新】的问题。

  • 前一个节点长度 < 254 字节,prevlen 需要用 1 字节的空间来保存这个长度值
  • 前一个节点长度 > 254 字节,prevlen 需要用 5 字节的空间来保存这个长度值
  • 本来都在250~253 之间,因为前面插入了新的导致最前面大于254,后面都跟着变了
    解决办法:控制每个链表节点中的压缩列表的元素个数,来规避连锁更新的问题。因为压缩列表元素越少,连锁更新带来的影响就越小。

3、Hash类型

Hash场景:购物车等。

键:cart:123 、字段:product:456、值:2 (用户123的购物车里有456产品,购物车里456产品的数量是2)

在 Redis 7.0 中,由 listpack 数据结构来实现。

listpack 是在压缩列表的基础上改造而来的,它没有压缩列表中记录前一个节点长度的字段了,只记录当前节点的长度,所以加入新元素的时候,不会影响其他节点的长度字段的变化,从而避免了压缩列表的连锁更新问题。

4、Set类型

Set 场景:一些聚合计算场景,比如点赞、共同关注等。

Set 类型的底层数据结构是由哈希表或整数集合实现的:

如果集合中的元素都是整数且元素个数小于默认的 512 个,Redis 会使用整数集合作为 Set 类型的底层数据结构;

如果集合中的元素不满足上面条件,则 Redis 使用哈希表作为 Set 类型的底层数据结构。

5、Zset类

Zset场景:排序场景,比如Rank排行榜、姓名排序等。

Zset 类型的底层数据结构是由 listpack 数据结构来实现。

Redis 后续版本又支持四种数据类型,它们的应用场景如下:

BitMap:

二值状态统计的场景,比如签到、判断用户登陆状态等;

HyperLogLog:

海量数据基数统计的场景,比如百万级网页访问量计数等;

GEO:.

存储地理位置信息的场景,比如滴滴叫车;

Stream:

消息队列,相比于基于 List 类型实现的消息队列,有这两个特有的特性:自动生成全局唯一消息ID,支持以消费组形式消费数据。

跳表

跳表其实是一种多层的有序链表,跳表在原有的有序链表基础上结合二分查找的思想增加了多级索引,通过索引来实现快速查询。

我们知道对于一个单链表来说,即使它有序,查找的时间复杂度还是O(n)。我们可以做一些优化,每两个结点提取一个"索引"到上一级,上一级有到下一级的指针。那如果链表数据是1-10,正常查找是O(n),有了索引之后就可以2、4、6、8这样来查找,甚至说数据多的话可以建立三层四层索引,以此来提升工作效率。

跳表的查询、插入、删除时间复杂度都是O(logn),空间复杂度是 O(n)

相关推荐
保持学习ing35 分钟前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
宇钶宇夕1 小时前
EPLAN 电气制图:建立自己的部件库,添加部件-加SQL Server安装教程(三)上
运维·服务器·数据库·程序人生·自动化
爱可生开源社区2 小时前
SQLShift 重磅更新:支持 SQL Server 存储过程转换至 GaussDB!
数据库
贾修行2 小时前
SQL Server 空间函数从入门到精通:原理、实战与多数据库性能对比
数据库·sqlserver
傲祥Ax2 小时前
Redis总结
数据库·redis·redis重点总结
一屉大大大花卷3 小时前
初识Neo4j之入门介绍(一)
数据库·neo4j
周胡杰4 小时前
鸿蒙arkts使用关系型数据库,使用DB Browser for SQLite连接和查看数据库数据?使用TaskPool进行频繁数据库操作
前端·数据库·华为·harmonyos·鸿蒙·鸿蒙系统
wkj0014 小时前
navicate如何设置数据库引擎
数据库·mysql
赵渝强老师4 小时前
【赵渝强老师】Oracle RMAN的目录数据库
数据库·oracle
暖暖木头4 小时前
Oracle注释详解
数据库·oracle