Redis ⽀持哪⼏种数据类型?适⽤场景,底层结构

目录

Redis 数据类型

一、String(字符串)

二、Hash(哈希)

三、List(列表)

四、Set(集合)

五、ZSet(sorted set:有序集合)

六、BitMap

七、HyperLogLog

八、GEO

九、Stream


Redis 数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

这 5 种数据类型是直接提供给用户使用的,是数据的保存形式,其底层实现主要依赖这 8 种数据结构:简单动态字符串(SDS)、LinkedList(双向链表)、Dict(哈希表/字典)、SkipList(跳跃表)、Intset(整数集合)、ZipList(压缩列表)、QuickList(快速列表)。

随着Redis版本更新,后面又支持了四种数据类型:BitMap(2.2新增)、HyperLogLog(2.8新增)、GEO(3.2新增)、Stream(5.0新增)。

Redis 5 种基本数据类型对应的底层数据结构实现如下表所示:

随着Redis版本更新,后面又支持了四种数据类型:BitMap(2.2新增)、HyperLogLog(2.8新增)、GEO(3.2新增)、Stream(5.0新增)。 

一、String(字符串)

简介

1. string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。

2. string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。

3. string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

应用场景

1.缓存:字符串类型可以用于缓存数据,例如缓存数据库查询结果、计算结果等。由于Redis的高性能和快速读写能力,使用字符串类型作为缓存可以大大提高系统的响应速度。

2.计数器:字符串类型可以用于实现计数器功能,例如统计网站的访问次数、用户的点赞数等。通过使用字符串类型的自增命令,可以方便地对计数器进行增加或减少操作。

3.分布式锁:字符串类型可以用于实现分布式锁,保证在分布式环境下的数据一致性和并发控制。通过设置一个唯一的字符串作为锁的值,并利用Redis的原子性操作,可以实现简单而高效的分布式锁机制。

4.会话管理:字符串类型可以用于存储用户的会话信息,例如用户登录状态、购物车内容等。通过将会话信息存储在字符串类型中,可以方便地进行读写操作,并且可以设置过期时间来自动清理过期的会话数据。

5.消息队列:字符串类型可以用于实现简单的消息队列,例如将消息内容作为字符串存储在Redis中,然后使用列表类型的命令进行消息的发布和订阅。

6.分布式缓存:字符串类型可以用于实现分布式缓存,例如将经过序列化的对象存储在字符串类型中,然后通过缓存命中来提高系统的性能和扩展性。

底层实现

String 类型的底层的数据结构实现主要是 long 和 SDS(简单动态字符串)。

二、Hash(哈希)

简介

1. Redis hash 是一个键值(key=>value)对集合。

2. Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

应用场景

存储对象:刚才我们讲到,String类型也可以存储对象,但我们为什么不推荐呢?

比如一个用户对象,属性包括姓名、年龄、性别、学号、学分等,因为客户端会先把这个对象序列化后存储为一个字符串的值,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。

这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改学分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。

Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口。

底层实现

上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap。

注意

Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。

三、List(列表)

简介

1.list 是按照插入顺序排序的string字符串链表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),它是一个有序集合。

2. 双向链表实现,两端添加元素的时间复杂度为 O(1)

3. 插入元素时,如果 key 不存在,redis 会为该 key 创建一个新的链表,如果链表中所有的元素都被移除,该 key 也会从 redis 中移除。

4. 列表最多可存储 2的32方 - 1 元素 (4294967295, 每个列表可存储40多亿)。

应用场景

1. 消息队列:redis 的 list 数据类型对于大部分使用者来说,是实现队列服务的最经济,最简单的方式。

2. 任务池:可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行,其实也有点类似消息队列。

3. “最新内容”:因为 list 结构的数据查询两端附近的数据性能非常好,所以适合一些需要获取最新数据的场景,比如新闻类应用的 “最近新闻”。

底层实现


LinkedList :普通链表,可以从双端访问,内存占用较高,内存碎片较多

ZipList :压缩列表,可以从双端访问,内存占用低,存储上限低(redis7.0后废弃,交友listpack数据结构来实现了)

QuickList:LinkedList + ZipList,可以从双端访问,内存占用较低,包含多个ZipList,存储上限高

3.2版本前redis采用LinkedList和ZipList来实现List,当元素数量小于512并且元素大小小于64字节时采用ZipList编码,超过则采用LinkedList编码。

3.2版本后,List 数据类型底层数据结构就只由 quicklist 实现了,替代了双向链表和压缩列表。

四、Set(集合)

简介

1. Set是一个无序string类型集合。

2. 通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

3. set 集合不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份

4. set 类型提供了多个 set 之间的聚合运算,如求交集、并集、补集,这些操作在 redis 内部完成,效率很高。

5. 集合最多可存储 2的32方 - 1 元素 (4294967295, 每个列表可存储40多亿)。

应用场景

set 类型的特点是“不重复且无序的一组数据”,并且具有丰富的计算功能,在一些特定的场景中可以高效的解决一般关系型数据库不方便做的工作。

  1. 唯一性数据存储:最基本的使用场景就是用来存储不重复的数据。你可以使用Set来存储用户ID、IP地址、邮箱地址等,确保数据的唯一性。
  2. 标签和标记系统:Set可以用于创建标签或标记系统。例如,你可以为文章、商品或其他实体创建一个包含相关标签的Set,以便后续快速检索。
  3. 关注和粉丝系统:在社交媒体或用户关系管理中,Set可以用来实现关注和粉丝系统。每个用户可以有一个Set,其中包含他们关注的其他用户或粉丝。
  4. 在线用户:Set可以用于跟踪在线用户。将用户ID添加到一个Set中,表示用户当前在线。通过检查Set中的成员,可以快速查找在线用户。
  5. 投票系统:Set可以用于实现投票系统。每个投票项目可以表示为一个Set,用户投票时将其ID添加到相应的Set中,确保每个用户只能投一次。
  6. 集合运算:Redis提供了多种Set运算,如交集、并集和差集。这些运算可以用于计算多个集合之间的共同元素、合并元素等。
  7. 排行榜和排名:Set可以用于创建排行榜系统。例如,每个元素代表一个玩家,分数作为元素的权重。可以通过有序集合操作获取排名和排行。
  8. 地理位置标记:Set可以用于存储地理位置数据,例如存储用户的经纬度坐标,然后利用Set运算来查找附近的位置。
  9. 过滤重复事件:如果你需要记录一系列事件,并且要确保事件不重复记录,可以使用Set来存储已经发生的事件,防止重复记录。

五、ZSet(sorted set:有序集合)

简介

1. Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

2. 不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。

3. zset的成员是唯一的,但分数(score)却可以重复。

应用场景

在集合类型的场景上加入排序就是有序集合的应用场景了。

  1. 根据好友的“亲密度”排序显示好友列表。
  2. 直播间里,粉丝打赏金额排序。
  3. 排行榜和计分系统:有序集合非常适合实现排行榜和计分系统。成员的分数可以表示玩家的得分、评分、积分等。你可以通过分数对成员进行排序,快速地获取前几名的排名。
  4. 时间序列数据:如果你需要存储带有时间戳的数据,有序集合可以根据时间戳(作为分数)进行排序,然后按时间范围快速查询数据。
  5. 最新消息:有序集合可以用来存储最新的消息,每个消息的分数可以是消息的时间戳,这样可以方便地获取最新的消息。
  6. 带权重的标签/标签云:在社交网络或标签系统中,你可以使用有序集合来存储标签,成员是标签,分数可以表示标签的热度、权重等。这可以用来实现标签云、热门标签等功能。

六、BitMap

简介

bitmap,位图。是一连串二进制数组,可通过偏移量offset定位元素,BitMap通过最小单位bit来进行0、1的设置,表示某个元素的值或状态,时间复杂度为O(1)。

bit是计算机中最小的单位,使用起来非常节省空间,特别适用于一些数据量大且使用二值统计的场景。

应用场景

  1. 签到统计:在签到打卡的场景中,我们只用记录签到(1)或未签到(0),所以它就是非常典型的二值状态。
  2. 判断用户登陆态

七、HyperLogLog

简介
HyperLogLog是一种用于「统计基数」的数据集合类型,基数统计就是指统计一个集合中不重复的元素个数。 统计规则是基于概率完成的,不是非常准确,标准误算率是 0.81%。

在redis中每个HyperLogLog键只需要花费12KB内存就可以计算接近2^64个不同元素的基数,非常节省空间。

应用场景

百万级网页 UV 计数

八、GEO

简介
主要用于存储地理位置信息并对其进行操作。

底层实现
GEO 本身并没有设计新的底层数据结构,而是直接使用了 Sorted Set 集合类型。

GEO 类型使用GeoHash编码方法实现了经纬度到Sorted Set中元素权重分数的转换,这其中的两个关键

机制就是「对二维地图做区间划分」和「对区间进行编码」。一组经纬度落在某个区间后,就用区间的编

码值来表示,并把编码值作为Sorted Set元素的权重分数。这样一来,我们就可以把经纬度保存到Sorted Set中,利用Sorted Set提供的“按权重进行有序范围查找”的特性,实现LBS服务(位置信息服务 Location-Based Service)中频繁使用的“搜索附近”的需求。

应用场景

滴滴叫车:假设车辆 ID 是 33,经纬度位置是(116.034579,39.030452),我们可以用一个 GEO 集合保存所有车辆的经纬度,集合 key 是 cars:locations。

执行下面命令就可以把 ID 号为 33 的车辆的当前经纬度位置存入 GEO 集合中:

GEOADD cars:locations 116.034579 39.030452 33

当用户想要寻找自己附近的网约车时,LBS 应用就可以使用 GEORADIUS 命令。

执行下面命令,redis会根据输入的用户的经纬度信息,查找以此经纬度为中心 5km内的车辆信息。GEOADD cars:locations 116.034579 39.030452 5 km ASC COUNT 10

九、Stream

简介
Redis Stream是Redis 5.0版本新增加的数据类型,Redis专门为消息队列设计的数据类型。

在Redis 5.0 Stream 没出来之前,消息队列的实现方式都有着各自的缺陷,例如:

发布订阅模式,不能持久化也就无法可靠的保存消息,并且对于离线重连的客户端不能读取历史消息的缺陷;

List实现消息队列的方式不能重复消费,一个消息消费完就会被删除,而且生产者需要自行实现全局唯一ID。

基于以上问题,Redis 5.0便推出了Stream类型也是此版本最重要的功能,用于完美地实现消息队列,它

支持消息的持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,让消息

队列更加的稳定和可靠。

应用场景

消息队列

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp接入BMapGL百度地图

下面代码兼容安卓APP和H5 百度地图官网:控制台 | 百度地图开放平台 应用类别选择《浏览器端》 /utils/map.js 需要设置你自己的key export function myBMapGL1() {return new Promise(function(resolve, reject) {if (typeof window.initMyBMapGL1 function) {r…

Docker+Nginx | Docker(Nginx) + Docker(fastapi)反向代理

在DockerHub搜 nginx,第一个就是官方镜像库,这里使用1.27.2版本演示 1.下载镜像 docker pull nginx:1.27.2 2.测试运行 docker run --name nginx -p 9090:80 -d nginx:1.27.2 这里绑定了宿主机的9090端口,只要访问宿主机的9090端口&#…

AmazonS3集成minio实现https访问

最近系统全面升级到https,之前AmazonS3大文件分片上传直接使用http://ip:9000访问minio的方式已然行不通,https服务器访问http资源会报Mixed Content混合内容错误。 一般有两种解决方案,一是升级minio服务,配置ssl证书&#xff0c…

人工智能|计算机视觉——微表情识别(Micro expression recognition)的研究现状

一、简述 微表情是一种特殊的面部表情,与普通的表情相比,微表情主要有以下特点: 持续时间短,通常只有1/25s~1/3s;动作强度低,难以察觉;在无意识状态下产生,通常难以掩饰或伪装;对微表情的分析通常需要在视频中,而普通表情在图像中就可以分析。由于微表情在无意识状态…

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

一、单选题 1、下面代码运行后出现的图像是?( ) import matplotlib.pyplot as plt import numpy as np x np.array([A, B, C, D]) y np.array([30, 25, 15, 35]) plt.bar(x, y) plt.show() A. B. C. D. 正确答案:A 答案…

Spring Aop+自定义注解实践(待完善日志)

目录 前言 1.引入依赖 2.SpringAop的用法举例 3. 自定义注解AOP的用法举例 3.1 关于Target注解补充 3.2 关于Retention注解补充 3.3 举例 前言 如果你不太理解aop的知识,请看我写的这篇文章,非常详细: Spring AOP(定义、…

OpenCV双目立体视觉重建

本篇文章主要给出使用opencv sgbm重建三维点云的代码,鉴于自身水平所限,如有错误,欢迎批评指正。 环境:vs2015 ,opencv3.4.6,pcl1.8.0 原始数据使用D455采集,图像已做完立体校正,如下…

【进阶系列】python简单爬虫实例

python有一个很强大的功能就是爬取网页的信息,这里是CNBlogs 网站,我们将以此网站为实例,爬取指定个页面的大标题内容。代码如下: 首先是导入库: # 导入所需的库 import requests # 用于发送HTTP请求 from bs4 impor…

Ease Monitor 会把基础层,中间件层的监控数据和服务的监控数据打通,从总体的视角提供监控分析

1. 产品定位 Ease Monitor 有如下的产品定位: 关注于整体应用的SLA。 主要从为用户服务的 API 来监控整个系统。 关联指标聚合。 把有关联的系统及其指示聚合展示。主要是三层系统数据:基础层、平台中间件层和应用层。 快速故障定位。 对于现有的系统…

Java学习笔记--数组常见算法:数组翻转,冒泡排序,二分查找

目录 一,数组翻转 二,冒泡排序 三,二分查找(一尺之锤,日取其半,万世不竭) 一,数组翻转 1.概述:数组对称索引位置上的元素互换,最大值数组序号是数组长度减一 创建跳板…

Python中Tushare(金融数据库)入门详解

文章目录 Python中Tushare(金融数据库)入门详解一、引言二、安装与注册1、安装Tushare2、注册与获取Token 三、Tushare基本使用1、设置Token2、获取数据2.1、获取股票基础信息2.2、获取交易日历2.3、获取A股日线行情2.4、获取沪股通和深股通成份股2.5、获…

网络编程(JAVA笔记第三十八期)

p.s.这是萌新自己自学总结的笔记,如果想学习得更透彻的话还是请去看大佬的讲解 目录 网络编程概念网络编程三要素IPInetAddress类端口号协议 UDP协议UDP通信程序(发送数据)UDP通信程序(发送数据)使用UDP写聊天室项目UDP的通信方式 TCP协议通过TCP协议实现多发多收通…

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域,数据可视化是一个至关重要的环节。通过可视化,我们可以直观地理解数据的特征和趋势,为数据分析和决策…

IDEA2023 SpringBoot整合MyBatis(三)

一、数据库表 CREATE TABLE students (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,age INT,gender ENUM(Male, Female, Other),email VARCHAR(100) UNIQUE,phone_number VARCHAR(20),address VARCHAR(255),date_of_birth DATE,enrollment_date DATE,cours…

PVE的优化与温度监控(二)—无法识别移动硬盘S.M.A.R.T信息的思考并解决

前情提要:空闲2.5英寸机械硬盘,直接放到PVE上测试NAS 使用,通过SATA线的方式让小主机不太美观,并且失去了前期调试的安全性。购入移动硬盘盒,缺点,USB 连接,会失去一些特性。比如本文中遇到的问…

记录下jekins新建个前端部署配置项

1 新建个item 2 输入项目名称,选择个新的工程或 或者搜个已存在的现有模板 3 添加一些描述 4 (可选)配置下构建历史保存情况 5 限制下构建节点和选择gitlab或者github 6 写下git仓库地址、账号密码以及分支 7 选择构建工具node以及版本 8 构建…

文件管理 II(文件的物理结构、存储空间管理)

一、文件的物理结构 文件实际上是一种抽象数据类型,我们要研究它的逻辑结构、物理结构,以及关于它的一系列操作。文件的物理结构就是研究文件的实现,即文件数据在物理存储设备上是如何分布和组织的。同一个问题有两个方面的回答:…

大数据新视界 -- 大数据大厂之 Impala 性能优化:跨数据中心环境下的挑战与对策(上)(27 / 30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

利用 GitHub 和 Hexo 搭建个人博客【保姆教程】

利用 GitHub 和 Hexo 搭建个人博客 利用 GitHub 和 Hexo 搭建个人博客一、前言二、准备工作(一)安装 Node.js 和 Git(二)注册 GitHub 账号 三、安装 Hexo(一)创建博客目录(二)安装 H…

ABAP开发-CO的底层表-物料价格分析CKM3

系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言一、物料分类账与CKM3二、CKM3界面分析三、CKM3的主要功能1、物料价格分析2、成本构成分析3、价格差异分析4、期间状态查看 四、物料分类账与CKM3的关系五、CKM3的底层表及数据支持1、核心数据表2、取数逻辑 总结 前言 …