当前位置: 首页 > news >正文

【Redis】redis基本数据类型详解(String、List、Hash、Set、ZSet)

目录

  • Redis
    • String(字符串)
    • List(列表)
    • Hash(字典)
    • Set(集合)
    • ZSet(有序集合)

Redis

Redis有5种基本的数据结构,分别为:string(字符串)、list(列表)、set(集合)、hash(哈希)和 zset(有序集合)。下面我们依次理解这五种基本数据类型。
在这里插入图片描述
除了String的底层是简单字符串SDS结构,其他类型底层都有两种数据结构支持。

String(字符串)

字符串是Redis最简单的数据结构。Redis所有的数据结构都是以唯一的key字符串作为名称,然后通过这个唯一key值来获取相应的value数据。不同类型的数据结构差异就在于value的结构不一样。
在这里插入图片描述
字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体使用JSON序列化成字符串,然后将序列化后的字符串塞进Redis来缓存。同样,取用户信息会经过一次反序列化的过程。

在这里插入图片描述
Redis的字符串是动态字符串,是可以修改的字符串,在内存中它是以字节数组的形式存在的,内部实现上采用预分配冗余空间的方式来减少内存的频繁分配,如上图所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串的长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。注意:字符串最大长度为512M

List(列表)

List的插入和删除操作特别快,时间复杂度为O(1),但是索引定位很慢,时间复杂度为O(n)。当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。

Redis的列表结构常常被用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进Redis的列表,另一个线程从这个列表中轮询数据进行处理。

快速列表

如果再深入一点,你会发现Redis底层存储的是一个叫做quicklist的一个结构。
在这里插入图片描述
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成quicklist。因为普通的链表需要的的附加指针空间太大,会比较浪费空间,而且会加重内存的碎片化。比如这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prevnext。所以Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能。又不会出现太大的空间冗余。

quicklist内部默认单个ziplist长度为8k字节,超过了这个字节数,就会新起有一个ziplist

Hash(字典)

字典(dict)是 Redis 服务器中出现最为频繁的复合型数据结构,除了 hash 结构的数据会用到字典外,整个 Redis 数据库的所有 key 和 value也组成了一个全局字典,还有带过期时间的 key 集合也是一个字典。zset 集合中存储 value 和 score 值的映射关系也是通过 dict 结构实现的。

Redis的字典是个无序字典(golang、java中字典也是无序字典),内部实现为数组+链表二维结构。第一维hash的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。

在这里插入图片描述
Redis为了高性能,不能堵塞服务,rehash采用的是渐进式策略。

在这里插入图片描述
渐进式rehash会在rehash的同时,保留新旧两个hash结构,查询时会同时查询两个hash结构,然后在后续的定时任务中以及hash的子指令中,循序渐进的将旧hash的内容一点点迁移到新的hash结构中。

当 hash 移除了最后一个元素之后,该数据结构自动被删除,内存被回收。hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。

hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情况再三权衡。

扩容条件

正常条件下,当hash表中元素的个数等于第一维数组的长度时,就会开始扩容,扩容的新数组是原数组大小的2倍。不过如果Redis这个在做bgsave,为了减少内存页的过多分离(Copy On Write),Redis尽量不去扩容(dict_can_resize),但是如果hash表已经非常满了,元素的个数已经达到了第一维数组长度的5倍(dict_force_resize_ratio),说明hash表已经过于拥挤了,这个时候就会强制扩容。

缩容条件

当 hash 表因为元素的逐渐删除而变得越来越稀疏时,Redis会对 hash 表进行缩容来减少hash表的第一维数组空间占用。缩容的条件是元素个数低于数组长度的10%。缩容不会考虑Redis是否正在做bgsave

Set(集合)

Redis的集合内部实现相当于一个特殊的字典,字典中所有的value都是一个值NULL,它内部的键值对是无序的唯一(自动排重)的。

当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。set结构可以用来存储活动中奖的用户ID,因为有去重功能,可以保证同一个用户不会中奖两次。

ZSet(有序集合)

zset可能是Redis提供的最为特色的数据结构,它也是在面试中面试官最爱问的数据结构。一方面它是一个set(字典结构),保证了内部value的唯一性,另一方面它可以给每个value赋予一个score,代表这个value的排序权重。它的内部实现用的是一种叫做【跳跃列表】的数据结构。

zset中最后一个value被移除后,数据结构自动删除,内存被回收。zset可以用来存粉丝列表,value值是粉丝的用户ID,score是关注时间。我们可以对粉丝列表按关注时间进行排序。

zset还可以用来存储学生的成绩,value值是学生的ID,score是他的考试成绩。我们可以对成绩按分数进行排序就可以得到他的名次。

跳跃列表

zset内部的排序功能是通过【跳跃列表】数据结构来实现的,它的结构非常特殊,也比较复杂。

因为 zset 要支持随机的插入和删除,所以它不好使用数组来表示。

先来看一个普通的链表结构:

在这里插入图片描述
我们需要这个链表按照 score 值进行排序。这意味着当有新元素需要插入时,要定位到特定位置的插入点,这样才可以继续保证链表是有序的。通常我们会通过二分查找来找到插入点,但是二分查找的对象必须是数组,只有数组才可以支持快速位置定位,链表做不到,那该怎么办呢?

想想一个创业公司,刚开始只有几个人,团队成员之间人人平等,都是联合创始人。随着公司的成长,人数渐渐变多,团队沟通成本随之增加。这时候就会引入组长制,对团队进行划分。每个团队会有一个组长。开会的时候分团队进行,多个组长之间还会有自己的会议安排。公司规模进一步扩展,需要再增加一个层级 — 部门,每个部门会从组长列表中推选出一个代表来作为部长。部长们之间还会有自己的高层会议安排。

跳跃列表就是类似于这种层级制,最下面一层所有的元素都会串起来。然后每隔几个元素挑选出一个代表来,再将这几个代表使用另外一级指针串起来。然后在这些代表里再挑出来二级代表 ,再串起来。最终就形成了金字塔结构。

在这里插入图片描述
【跳跃列表】之所以【跳跃】,是因为内部的元素可能【身兼数职】,比如上图中间的这个元素,同时处于 L0、L1和L2层,可以快速再不同层次之间进行【跳跃】。

定位插入点时,先在顶层进行定位,然后下潜到下一级定位,一直下潜到最底层找到合适的位置,将新元素插进去。那新插入的元素如何才有机会【身兼数职】呢?

跳跃列表采取一个随机策略来决定新元素可以兼职到第几层。

首先 L0 层肯定是100%了,L1层只有50%的概率,L2层只有25%的概率,L3层只有12.5%的概率,一直随机到最顶层L31层。绝大多数元素都过不了几层,只有极少数元素可以深入到顶层。列表中的元素越多,能够深入的层次就越深,能进入到顶层的概率就会越大。

查找过程

请添加图片描述

  • 从第2层开始,因为 1 节点比 51 节点小,向后比较。

  • 21 节点比 51 节点小,继续向后比较,后面就是NULL了,所以从 21 节点向下到第 1 层

  • 到第 1 层,41 节点比 51 节点小,继续向后, 61 节点比 51 节点大,所以从 41 向下

  • 到第 0 层,51 节点为要查找的节点,节点被找到,共查找 4 次。

问题:为什么不采用树或者红黑树,或者像MySQL一样采用B树?(跳表和其他数据类型的区别)

两个核心问题:

  1. Redis的定位,也即问题的背景。Redis是一个内存数据库,在时间复杂度差不多的情况下,优先选择内存占用较小(也就是空间复杂度较低)的数据结构,而且相对而言跳表的实现起来更简单(它们更容易实现、调试等等)。
  2. 跳表和树的区别,尤其是数据结构上的区别。树需要大量的指针来记录节点信息,树越高,开销越大。跳表在这方面要好得多。在插入数据时,跳表可能会调整索引,树需要再平衡,各有特点。

相关文章:

【Redis】redis基本数据类型详解(String、List、Hash、Set、ZSet)

目录 RedisString(字符串)List(列表)Hash(字典)Set(集合)ZSet(有序集合) Redis Redis有5种基本的数据结构,分别为:string(字符串)、list(列表)、set(集合)、hash(哈希&a…...

ubuntu源码安装aria2

github:GitHub - aria2/aria2: aria2 is a lightweight multi-protocol & multi-source, cross platform download utility operated in command-line. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink. 发行说明:GitHub - aria2/aria2 at releas…...

【多任务案例:猫狗脸部定位与分类】

【猫狗脸部定位与识别】 1 引言2 损失函数3 The Oxford-IIIT Pet Dataset数据集4 数据预处理4 创建模型输入5 自定义数据集加载方式6 显示一批次数据7 创建定位模型8 模型训练9 绘制损失曲线10 模型保存与预测 1 引言 猫狗脸部定位与识别分为定位和识别,即定位猫狗…...

.Net 锁的介绍

在.NET中,有多种锁机制可用于多线程编程,用来确保线程安全和共享资源的同步。以下是.NET中常见的锁机制: 1. **Monitor(互斥锁):** `Monitor` 是.NET中最基本的锁机制之一。它使用 `lock` 关键字实现,可以确保在同一时刻只有一个线程能够访问被锁定的代码块。`Monitor`…...

Office 2021 小型企业版商用办公软件评测:提升工作效率与协作能力的专业利器

作为一名软件评测人员,我将为您带来一篇关于 Office 2021 小型企业版商用办公软件的评测文章。在这篇评测中,我将从实用性、使用场景、优点和缺点等多个方面对该软件进行客观分析,在专业角度为您揭示它的真正实力和潜力。 一、实用性&#xf…...

Monkey测试

一:测试环境搭建 1:下载android-sdk_r24.4.1-windows 2:下载Java 3:配置环境变量:关于怎么配置环境变量(百度一下:monkey环境搭建,) 二:monkey测试&#xff1…...

wzx-jmw:NFL合理,但可能被颠覆。2023-2024

As well known by all, NFL is ... 没有免费的午餐理论 No Free Lunch Theorem_免费午餐理论-CSDN博客 However, if we......

密码技术 (5) - 数字签名

一. 前言 前面在介绍消息认证码时,我们知道消息认证码虽然可以确认消息的完整性,但是无法防止否认问题。而数字签名可以解决否认的问题,接下来介绍数字签名的原理。 二. 数字签名的原理 数字签名和公钥密码一样,也有公钥和私钥&am…...

php实战案例记录(10)单引号和双引号的用法和区别

在 PHP 中,单引号和双引号都被用于表示字符串。它们有一些共同之处,但也有一些明显的区别。 解析变量: 双引号允许解析变量,而单引号不会。在双引号中,你可以直接在字符串中插入变量,而不需要进行额外的连接…...

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石②

嵌入式Linux应用开发-基础知识-第十九章驱动程序基石② 第十九章 驱动程序基石②19.3 异步通知19.3.1 适用场景19.3.2 使用流程19.3.3 驱动编程19.3.4 应用编程19.3.5 现场编程19.3.6 上机编程19.3.7 异步通知机制内核代码详解 19.4 阻塞与非阻塞19.4.1 应用编程19.4.2 驱动编程…...

trycatch、throw、throws

在Java中,try-catch、throw和throws是用于处理异常的重要关键字和机制,它们的作用如下: try-catch:try-catch 是用于捕获和处理异常的语句块。在try块中放置可能引发异常的代码。如果在try块中的代码引发了异常,控制流会跳转到与异常类型匹配的catch块。在catch块中,可以…...

问 ChatGPT 关于 GPT 的事情:数据准备篇

一、假如你是一名人工智能工程师,手里有一个65B的GPT大模型,但你需要一个6B左右的小模型,你会怎么做? 答:作为人工智能工程师,如果我手里有一个65B的GPT大模型,而我需要一个6B左右的小模型&…...

leetcode_17电话号码的组合

1. 题意 输出电话号码对应的字母左右组合 电话号码的组合 2. 题解 回溯 class Solution { public:void gen_res(vector<string> &res, vector<string> &s_m,string &digits, string &t, size_t depth) {if (depth digits.size()) {if ( !t.em…...

记录使用vue-test-utils + jest 在uniapp中进行单元测试

目录 前情安装依赖package.json配置jest配置测试文件目录编写setup.js编写第一个测试文件jest.fn()和jest.spyOn()jest 解析scss失败测试vuex$refs定时器测试函数调用n次手动调用生命周期处理其他模块导入的函数测试插槽 前情 uniapp推荐了测试方案dcloudio/uni-automator&…...

《C和指针》笔记30:函数声明数组参数、数组初始化方式和字符数组的初始化

文章目录 1. 函数声明数组参数2. 数组初始化方式2.1 静态初始化2.2 自动变量初始化 2.2 字符数组的初始化 1. 函数声明数组参数 下面两个函数原型是一样的&#xff1a; int strlen( char *string ); int strlen( char string[] );可以使用任何一种声明&#xff0c;但哪个“更…...

VBA技术资料MF64:遍历单元格搜索字符并高亮显示

【分享成果&#xff0c;随喜正能量】不要在乎他人的评论&#xff0c;不必理论与他人有关的是非&#xff0c;你只要做好自己就够了。苔花如米小&#xff0c;也学牡丹开。无论什么时候&#xff0c;都要有忠于自己的勇气&#xff0c;去做喜欢的事&#xff0c;去认识喜欢的人&#…...

一键智能视频编辑与视频修复算法——ProPainter源码解析与部署

前言 视频编辑和修复确实是随着电子产品的普及变得越来越重要的技能。有许多视频编辑工具可以帮助人们轻松完成这些任务如&#xff1a;Adobe Premiere Pro&#xff0c;Final Cut Pro X&#xff0c;Davinci Resolve&#xff0c;HitFilm Express&#xff0c;它们都提供一些视频修…...

Flutter开发环境的配置

2023-10最新版本 flutter SDK版本下载地址 https://flutter.cn/docs/development/tools/sdk/releases gradle各版本快速下载地址 https://blog.csdn.net/ii950606/article/details/109105402 JAVA SDK下载地址 https://www.oracle.com/java/technologies/downloads/#java…...

【超详细】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…...

Linux命令(92)之rm

linux命令之rm 1.rm介绍 linux命令rm是用来删除一个或多个文件/目录&#xff0c;由于其删除的不可逆性&#xff0c;建议在日常工作中一定要慎用 2.rm用法 rm [参数] 文件/目录 rm常用参数 参数说明-r递归删除文件或目录-f不提示强制删除-i删除文件或目录前进行确认-v详细显…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...