Redis常用数据结构及原理

news2025/2/1 11:51:57

Redis常用六种数据类型

Redis 支持多种数据类型,每种类型都具有不同的特性和用途。以下是 Redis 中常见的数据类型:

一、字符串(String)

1、基本介绍

字符串是最基本的数据类型,可以存储任意类型的数据,如文本、数字或序列化对象。可以使用字符串相关的命令对其进行操作,如设置值(SET)、获取值(GET)、增加数值(INCR)、追加字符串(APPEND)等。

2、底层数据结构和原理

在 Redis 中,字符串类型的底层数据结构和原理是简单动态字符串(SDS,Simple Dynamic String)。

简单动态字符串是 Redis 自己实现的一种字符串结构,相比于传统的 C 字符串(以空字符 ‘\0’ 结尾的字符数组),简单动态字符串具有以下优势:

  • O(1) 时间复杂度的修改操作:简单动态字符串通过维护字符串长度和可用空间的变量,可以在 O(1) 时间复杂度内进行字符串的修改操作,而不需要像传统 C 字符串那样进行内存拷贝和分配。

  • 动态扩容和缩容:简单动态字符串在需要扩容时,可以按需动态地增加内存空间,而不是事先分配固定大小的缓冲区。这种动态扩容的机制使得字符串的长度可以根据需要进行自由调整,节省了内存空间。

  • 二进制安全:简单动态字符串可以存储任意二进制数据,不仅仅限于文本字符串。这使得 Redis 可以在字符串类型中存储和处理二进制数据,而不会受到 C 字符串的限制。

  • 内存预分配和惰性空间释放:简单动态字符串在进行扩容时,会预先分配一定的额外空间,以减少频繁的内存分配操作。同时,在字符串缩短时,不会立即释放多余的空间,而是保留一部分空间,以备后续使用,从而提高了性能。

总之,简单动态字符串是 Redis 中字符串类型的底层数据结构,通过动态扩容和缩容、O(1) 时间复杂度的修改操作等特性,提供了高效的字符串操作。这种数据结构使得 Redis 的字符串类型非常适用于存储和处理各种类型的数据,包括文本和二进制数据。

这个其实和Java中的ArrayList的实现比较像,ArrayList使用的是动态数组。如果读者比较感兴趣的话,后续我可以单独写一篇文章来着重讲述两者的区别。

二、哈希(Hash)

1、基本介绍

哈希是一种键值对集合,类似于对象或字典。每个哈希可以存储多个字段和对应的值。可以使用哈希相关的命令对其进行操作,如设置**字段值(HSET)、获取字段值(HGET)、获取全部字段和值(HGETALL)**等。

2、底层数据结构和原理

在 Redis 中,Hash(哈希)的底层数据结构是哈希表(Hash Table)。

哈希表是一种基于键值对的数据结构,通过哈希函数将键映射到存储位置,实现了高效的键值查找和插入操作。在 Redis 的哈希中,哈希表被用来存储哈希的键值对。

Hash大家应该都比较熟悉了,这里简单讲一下Redis 中哈希底层数据结构和原理的一些关键点:

  • 哈希表优势:使用哈希表作为哈希的底层数据结构有几个优势。首先,通过哈希表,可以以常数时间复杂度 O(1) 来执行插入、删除和查找操作。其次,哈希表可以高效地处理大量的键值对数据,具有良好的扩展性。

  • 哈希表存储键值对:在 Redis 中,每对哈希的键值对被存储为哈希表的键值对。哈希表的键被称为字段(field),而哈希表的值被称为值(value)。通过哈希表的键,可以快速检索和操作哈希中的键值对。

  • 哈希表的键冲突处理:由于哈希函数的输出空间有限,不同的键可能映射到相同的哈希表位置,这就是所谓的键冲突。为了解决键冲突,Redis 使用链地址法(Separate Chaining)来处理相同哈希值的键。具体来说,Redis 将具有相同哈希值的键值对放在同一个链表中,通过链表来存储冲突的键值对。

  • 哈希表的扩容和缩容:为了保持哈希表的高效性能,Redis 在哈希表达到一定负载因子时会自动进行扩容操作。扩容操作涉及重新计算哈希函数和重新分配空间,以便保持较低的键冲突率。同样,当哈希表的使用率较低时,Redis 会自动进行缩容操作,以节省内存空间。

  • 哈希的常用操作:Redis 提供了一系列命令来操作哈希,如添加字段和值(HSET)、获取值(HGET)、删除字段(HDEL)等。这些命令通过操作底层的哈希表来实现哈希的操作。

Redis 中的哈希数据类型通过使用哈希表作为底层数据结构,实现了高效的键值查找和插入操作。这种数据结构使得 Redis 的哈希非常适用于存储和操作具有键值对结构的数据,如用户信息、配置信息等。

三、列表(List)

1、基本介绍

列表是一个有序的字符串元素集合,可以在列表的两端进行插入或删除操作。列表可以用作队列或栈。您可以使用列表相关的命令对其进行操作,如插入元素到列表头(LPUSH)、弹出列表尾部元素(RPOP)、获取指定范围的元素(LRANGE)等。

2、底层数据结构和原理

在 Redis 中,List(列表)的底层数据结构是双向链表(doubly linked list)。(注:Java中的LinkedList底层也是双向链表,可以对比学习。)

双向链表是一种由多个节点组成的数据结构,每个节点包含一个值和两个指针,分别指向前一个节点和后一个节点。在 Redis 中,每个列表都由一个双向链表来实现,列表的每个元素都存储在一个节点中。

Redis 通过使用双向链表作为列表的底层数据结构,实现了对列表的高效操作。以下是一些关于 Redis 列表底层数据结构和原理的重要细节:

  • 双向链表优势:使用双向链表作为列表的底层数据结构有几个优势。首先,它允许在列表的两端进行高效的插入和删除操作,时间复杂度为 O(1)。其次,双向链表可以按照顺序遍历和反向遍历列表,使得在有序列表中执行范围操作非常高效。

  • 列表的头节点和尾节点:Redis 中的列表有一个特殊的头节点和尾节点,分别表示列表的开头和结尾。这些节点不包含实际的值,只是作为指示列表边界的标记。它们的存在使得在列表两端执行插入和删除操作更加高效。

  • 列表的节点结构:每个列表节点包含三个主要部分。第一个部分是前置节点指针,指向前一个节点;第二个部分是后置节点指针,指向后一个节点;第三个部分是值,存储实际的列表元素。

  • 列表的头指针和尾指针:Redis 中的列表有两个指针,分别指向列表的头节点和尾节点。这些指针使得在列表两端执行插入、删除和访问操作更加方便和高效。

  • 列表的常用操作:Redis 提供了一系列命令来操作列表,如插入元素到列表头部(LPUSH)、插入元素到列表尾部(RPUSH)、从列表头部弹出元素(LPOP)、从列表尾部弹出元素(RPOP)等。这些命令通过操作双向链表的节点来实现列表的操作。

Redis 中的列表数据类型通过使用双向链表作为底层数据结构,实现了高效的插入、删除和访问操作。这种数据结构使得 Redis 列表非常适用于队列、栈、任务列表等应用场景,同时提供了丰富的命令和操作来满足不同的需求。

四、集合(Set)

1、基本介绍

集合是一组唯一的、无序的字符串元素集合。集合支持添加、删除和判断元素是否存在的操作。您可以使用集合相关的命令对其进行操作,如添加元素到集合(SADD)、删除元素(SREM)、判断元素是否存在(SISMEMBER)等。

2、底层数据结构和原理

在 Redis 中,Set(集合)的底层数据结构是哈希表(Hash Table)。

哈希表是一种基于键值对的数据结构,它通过哈希函数将键映射到存储位置,从而实现高效的键值查找和插入操作。在 Redis 的集合中,哈希表被用来存储集合的元素。

以下是 Redis 中集合底层数据结构和原理的一些关键点:

  • 哈希表优势:使用哈希表作为集合的底层数据结构有几个优势。首先,通过哈希表,可以以常数时间复杂度 O(1) 来执行插入、删除和查找操作。其次,哈希表可以高效地处理大量的键值对数据,具有良好的扩展性。

  • 哈希表存储集合元素:在 Redis 中,每个集合元素被存储为哈希表的键,而哈希表的值则被设置为一个固定的空占位符。通过哈希表的键,可以快速检索和操作集合中的元素。

  • 哈希表的键冲突处理:由于哈希函数的输出空间有限,不同的键可能映射到相同的哈希表位置,这就是所谓的键冲突。为了解决键冲突,Redis 使用链地址法(Separate Chaining)来处理相同哈希值的键。具体来说,Redis 将具有相同哈希值的键放在同一个链表中,通过链表来存储冲突的键值对。

  • 哈希表的扩容和缩容:为了保持哈希表的高效性能,Redis 在哈希表达到一定负载因子时会自动进行扩容操作。扩容操作涉及重新计算哈希函数和重新分配空间,以便保持较低的键冲突率。同样,当哈希表的使用率较低时,Redis 会自动进行缩容操作,以节省内存空间。

  • 集合的常用操作:Redis 提供了一系列命令来操作集合,如添加元素到集合(SADD)、从集合中移除元素(SREM)、判断元素是否存在于集合中(SISMEMBER)等。这些命令通过操作底层的哈希表来实现集合的操作。

Redis 中的集合数据类型通过使用哈希表作为底层数据结构,实现了高效的插入、删除和查找操作。这种数据结构使得 Redis 集合非常适用于存储和操作唯一值的场景,并提供了丰富的命令和操作来满足不同需求。

五、有序集合(Sorted Set)

1、基本介绍

有序集合是一种在集合基础上增加了一个分数(score)的数据结构。每个元素都有一个唯一的值和一个对应的分数,通过分数可以对元素进行排序。您可以使用有序集合相关的命令对其进行操作,如添加元素到有序集合(ZADD)、根据分数范围获取元素(ZRANGEBYSCORE)、获取指定排名范围的元素(ZRANGE)等。

2、底层数据结构和原理

在 Redis 中,Sorted Set(有序集合)的底层数据结构是跳跃表(Skip List)和哈希表(Hash Table)的结合使用。

跳跃表是一种有序数据结构,类似于链表,但在每个节点中添加了多个指向其他节点的指针,从而实现高效的查找和范围操作。哈希表用于存储每个成员及其对应的分数。

以下是 Redis 中有序集合底层数据结构和原理的一些关键点:

  • 跳跃表:有序集合使用跳跃表作为有序数据的主要存储结构。跳跃表中的每个节点都包含一个成员和一个分数,节点按照成员的字典序进行排序。通过多个层级的指针,跳跃表可以快速跳过一些节点,从而加快查找速度。

  • 跳跃表的层级:跳跃表由多个层级组成,每个层级都是一个有序链表。最底层是包含所有成员的完整链表,而上层则是通过“跳跃”的方式连接较少的节点。这种层级结构使得在跳跃表中查找成员的时间复杂度为 O(log n)。

  • 哈希表:除了跳跃表,Redis 还使用哈希表来存储每个成员及其对应的分数。哈希表通过将成员作为键、分数作为值来存储数据。这样,当需要根据成员进行查找或更新时,可以通过哈希表快速定位到对应的节点。

  • 跳跃表和哈希表的结合使用:通过将跳跃表和哈希表结合使用,Redis 实现了有序集合数据类型的高效操作。跳跃表提供了快速的有序查找和范围操作,而哈希表则提供了快速定位成员的能力。

  • 有序集合的常用操作:Redis 提供了一系列命令来操作有序集合,如添加成员和分数(ZADD)、根据分数范围获取成员(ZRANGEBYSCORE)、获取成员的排名(ZRANK)等。这些命令通过操作底层的跳跃表和哈希表来实现有序集合的操作。

Redis 中的有序集合数据类型通过使用跳跃表和哈希表的结合,实现了高效的有序集合操作。跳跃表提供了快速的查找和范围操作,而哈希表提供了快速定位成员的能力。这种数据结构使得 Redis 有序集合非常适用于实现排行榜、计数器和范围查询等应用场景。

六、Bitmaps

1、基本介绍

位图是一种使用二进制位来存储和操作数据的数据结构。您可以使用位图相关的命令对其进行操作,如设置位(SETBIT)、获取位(GETBIT)、对多个位进行逻辑操作(BITOP)等。

除了以上常见的数据类型,Redis 还支持其他数据类型,如地理位置(Geospatial)、流(Stream)等。每种数据类型都有各自的用途和适用场景,您可以根据具体的需求选择合适的数据类型来存储和操作数据。

2、底层数据结构和原理

在 Redis 中,Bitmaps(位图)的底层数据结构是字符串(String)。

字符串是 Redis 中最基本的数据结构,可以存储二进制数据。在 Bitmaps 中,每个位(bit)都被存储为字符串中的一个字符,可以表示为 0 或 1。Redis 使用字符串来表示位图,并提供了一系列命令来操作位图数据。

以下是 Redis 中位图底层数据结构和原理的一些关键点:

  • 字符串存储位:在 Redis 中,每个位都由一个字符来表示。位图使用 0 或 1 来表示位的状态,通常使用字符 “0” 和 “1” 分别表示位值为 0 或 1。

  • 字符串的位操作:Redis 提供了一些位操作命令,如设置位(SETBIT)、获取位(GETBIT)、对多个位进行逻辑操作(BITOP)等。这些命令通过操作字符串的位来实现位图的操作。

  • 字符串的二进制存储:Redis 使用字节序列来存储字符串,每个字节可以表示 8 个位。位图中的每个位会转换成对应字节中的某一位。

  • 位图的大小:Redis 中的位图可以非常大,可以有 2^32 = 4294967296 个位,即可以表示一个长度为 4294967296 的位序列。

  • 位图的应用:位图在 Redis 中广泛应用于各种场景,如统计在线用户、记录用户行为、判断某个元素是否存在等。由于位图的存储非常紧凑,可以有效地节省存储空间。

请注意,位图虽然非常高效,但它是以整个字符串作为单位进行操作的,如果只需要操作其中的某些位,可能会涉及到整个字符串的读取和写入,可能会对性能产生影响。因此,在使用位图时,需要根据实际需求和数据规模进行权衡和设计。

除了以上常见的数据类型,Redis 还支持其他数据类型,如地理位置(Geospatial)、流(Stream)等。每种数据类型都有各自的用途和适用场景,可以根据具体的需求选择合适的数据类型来存储和操作数据。

欢迎关注我的公众号,除了分享一些技术文章,还会分享一些工作经验和有趣的事。
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/762861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Simulink仿真模块 - Repeating Sequence

Repeating Sequence:生成任意形状的周期信号 在仿真库中的位置为:Simulink / Sources 模型为: 说明 Repeating Sequence 模块可以输出波形由 Time values 和 Output values 参数指定的周期性标量信号。Time values 参数指定输出时间向量。Output values 参数指定输出时间对应…

Windows 组策略 部署打印机

一、服务端 1、打印机管理:添加打印机 2、选择打印机 3、第一次安装,选择这个 4、下载驱动,从磁盘安装 5、已成功安装 6、选中打印机右击属性:列出目录 7、创建一个组策略 8、组策略设置 用户设置 → 首选项 → 控制面板 → 打印…

12_基于 I2C 协议的 EEPROM 驱动控制

12_基于 I2C 协议的 EEPROM 驱动控制 1. I2C协议1.1 I2C通信协议1.2 I2C物理层1.3 I2C协议层1.3.1 单字节数据的写入1.3.2 页写数据写入1.3.3 随机读取操作1.3.4 顺序读取操作 2. EEPROM2.1 板载 EEPROM 实物图2.2 板载 EEPROM 部分原理图 3. 实验目标4. 模块框图4.1 顶层模块4…

进程、线程、调度基础知识

程序是一些保存在磁盘上的指令的有序集合,是静态的,说白了就是一堆有逻辑的代码。包装成一个软件。 一、进程 是程序一次执行的过程。每个进程有自己独立的内存空间,一个进程有多个线程。 并行和并发对比: 字面意思而言&#xf…

Java 反射四大核心类:Class、Constructor、Method、 Filed

目录 反射可以做到的事情 反射重要的4个类 Class类 Class类的类图 Class类常用方法 获取Class类对象4种方式 基本数据类型的Class类对象和包装类的Class类对象 Field类 Method类 Constructor类 反射的简单使用 反射可以做到的事情 在不修改源码的情况下,…

Redis主从复制环境部署

文章目录 Redis主从复制:原理:全同步过程:增量同步过程:主从复制配置:关闭防火墙和Selinux(三台都要)修改bindIP:node3node2master 以138为主,140,141为从检查…

redis 跳跃表、字典、压缩列表、快速列表

redis 跳跃表、字典、压缩列表、快速列表 1. 跳跃表 ​ 跳跃表是有序集合的底层实现。就是将有序集合的部分节点进行分层。每一层都是有序集合,并且层次越高,节点数量就越少。最底层的包含所有节点数据。典型的空间换时间。 ​ Redis中的跳跃表&#x…

使用 FreeCAD 软件打开 stp、dwg、dxf 等模型文件并测量零件尺寸

1、下载安装 FreeCAD 软件 https://www.freecad.org/downloads.php 2、打开 stp 等模型文件,选择 framework 查看方式(只显示点、线) 3、切换到 Part 菜单栏 4、打开 Measure Linear 工具(测量线性距离) 5、选择两个…

初探KVM虚拟化技术:新手指南

首先了解一下虚拟化的概念 虚拟化是指对资源的逻辑抽象、隔离、再分配、管理的一个过程,通常对虚拟化的理解有广义狭义之分。广义包括平台虚拟化、应用程序虚拟化、存储虚拟化、网络虚拟化、设备虚拟化等等。狭义的虚拟化专门指计算机上模拟运行多个操作系统平台。…

安卓设备监听全部输入信号

前言: 最近团队收到一个产品需求,需要监听安卓设备上用户是否有输入行为,以免定制推荐的时候打搅到用户。这里指的是设备上所有应用的输入行为,而不是单指某一个应用。 这个需求还是蛮有挑战性的,需要涉及到很多FW层…

Java设计模式之模板模式

1. 模板模式介绍 1、模板模式即模板方法模式自定义了一个操作中的算法骨架,而将步骤延迟到子类中,使得子类可以不改变一个算法的结构,可以自定义该算法的某些特定步骤; 2、父类中提取了公共的部分代码,便于代码复用&am…

PyTorch深度学习实战(5)——计算机视觉基础

PyTorch深度学习实战(5)——计算机视觉基础 0. 前言1. 图像表示2. 将图像转换为结构化数组2.1 灰度图像表示2.2 彩色图像表示 3 利用神经网络进行图像分析的优势小结系列链接 0. 前言 计算机视觉是指通过计算机系统对图像和视频进行处理和分析&#xff…

Scala(二)

第2章 变量和数据类型 2.1 注释 Scala注释使用和Java完全一样。 注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去体现。 1)基本语法 (1)单行注释:// (2&#xff0…

高时空分辨率、高精度一体化预测技术的风、光、水自动化预测技术的应用

第一章 预测平台讲解及安装 一、高精度气象预测基础理论介绍 综合气象观测数值模拟模式; 全球预测模式、中尺度数值模式; 二、自动化预测平台介绍 Linux系统 Crontab定时任务执行机制 Bash脚本自动化编程 硬件需求简介 软件系统安装 …

独立站该怎么带来客户流量?来看看这五大方法吧!

建立独立站是为了让更多的人知道你的品牌和产品,从而吸引潜在客户并转化为销售机会。以下是一些可以帮助独立站带来客户流量的方法: 01.SEO(搜索引擎优化): 优化网站的SEO,使得搜索引擎能够更好地找到你的…

MyBatis之慎用association

这里先总结一下 association 存在的问题。 一、内嵌查询时存在报错Id找不到及内存溢出隐患 二、一对多关系数据重复问题 三、多层嵌套内层 association 查询结果为null 或 非预期的值 一、内嵌查询时存在报错Id找不到及内存溢出隐患 参考: https://www.lmlphp.co…

DP358/321/323/324运算放大器芯片

DP358、DP321、DP323、DP324是一款低噪声、低压、低 功耗轨到轨输出运放大器,该系列放大器的增益带宽为 11MHz,压摆率为 8.5V/uS,其中DP323 在掉电工作模式下待机电流小于1uA。该系列放大器可以广泛应用于各种电子产品领域。 主要特性: 轨到轨最大输入…

电脑提示msvcr110.dll丢失怎样修复呢?推荐三个修复方法

Windows系统总是不可避免会出现系统报错,提示msvcr110.dll丢失,无法运行启动软件程序,主要就是由于系统的msvcr110.dll丢失或者损坏。msvcr110.dll是Microsoft Visual C Redistributable软件包中的一个文件,它是由Microsoft Visua…

【文生图系列】Stable Diffusion Webui安装部署过程中bug汇总(Linux系统)

文章目录 bugs虚拟环境pythongfpgan和cython bugs 看网上部署stable diffusion webui的教程,很简单。而且我也有部署stable diffusion v1/v2的经验,想着应该会很快部署完stable diffusion webui,但是没想到在部署过程中,遇到各种…

【数据分析 - 基础入门之pandas篇③】- pandas数据结构——DataFrame

文章目录 前言一、DataFrame创建1.1 字典创建1.2 NumPy二维数组创建 二、DataFrame切片2.1 行切片2.2 列切片2.3 行列切片 三、DataFrame运算3.1 DataFrame和标量的运算3.2 DataFrame之间的运算3.3 Series和DataFrame之间的运算 四、DataFrame多层次索引4.1 多层次索引构造1.隐…