【数据库】Redis数据类型详解

news2024/11/15 22:26:04

目录

  • 一、5种基本数据类型
    • 1. String
    • 2. List
    • 3. Hash
    • 4. Set
    • 5. ZSet
  • 二、3种特殊类型
    • 1. Bitmap
    • 2. HyperLogLog
    • 3. Geospatial index

一、5种基本数据类型

  • Redis 共有 5 种基本数据结构:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)

  • 这 5 种数据结构底层实现主要依赖这 8 种数据结构:简单动态字符串(SDS)、LinkedList(双向链表)、Hash Table(哈希表)、SkipList(跳跃表)、Intset(整数集合)、ZipList(压缩列表)、QuickList(快速列表)

Redis 基本数据结构的底层数据结构实现如下:

StringListHashSetZset
SDSLinkedList/ZipList/QuickListHashTable、ZipListZipList、IntsetZipList、SkipList

1. String

在这里插入图片描述

  1. 常用命令
    在这里插入图片描述
  2. 底层实现:SDS 简单动态字符串
    在这里插入图片描述
struct sdshdr{
    //int 记录buf数组中未使用字节的数量 如上图free为0代表未使用字节的数量为0
    int free;
    //int 记录buf数组中已使用字节的数量即sds的长度 如上图len为5代表未使用字节的数量为5
    int len;
    //字节数组用于保存字符串 sds遵循了c字符串以空字符结尾的惯例目的是为了重用c字符串函数库里的函数
    char buf[];
}c
  1. SDS与C字符串的区别(优势)
  • 获取字符串的长度只需O(1)
  • 不会发生缓冲区溢出的情况
  • 减少内存重新分配次数:
    • 空间预分配:预先分配比实际请求的还要大的空间
    • 惰性空间释放:不是立即使用内存重分配来回收缩短出来的字节,而是使用free属性记录起来,并等待将来使用
  • 二进制安全:不会产生错误识别\0的情况

2. List

在这里插入图片描述

  1. 常用命令
    在这里插入图片描述
  2. 底层实现:双向链表
    在这里插入图片描述

3. Hash

在这里插入图片描述

  1. 常用命令
    在这里插入图片描述
  2. 底层实现:散列表,两个
    在这里插入图片描述
typedef struct dict{
         //类型特定函数
         dictYType *type;
         //私有数据
         void *privdata;
         //哈希表-见2.1.2
         dictht ht[2];
         //rehash 索引 当rehash不在进行时 值为-1
         int trehashidx; 
}dict;
  1. rehash

包含两个哈希表 dictht,这是为了方便进行 rehash 操作。在扩容时,将其中一个 dictht 上的键值对 rehash 到另一个 dictht 上面,完成之后释放空间并交换两个 dictht 的角色

typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

rehash 操作不是一次性完成,而是采用渐进方式,这是为了避免一次性执行过多的 rehash 操作给服务器带来过大的负担。

渐进式 rehash 通过记录 dict 的 rehashidx 完成,它从 0 开始,然后每执行一次 rehash 都会递增。例如在一次 rehash 中,要把 dict[0] rehash 到 dict[1],这一次会把 dict[0] 上 table[rehashidx] 的键值对 rehash 到 dict[1] 上,dict[0] 的 table[rehashidx] 指向 null,并令 rehashidx++。

在 rehash 期间,每次对字典执行添加、删除、查找或者更新操作时,都会执行一次渐进式 rehash。

采用渐进式 rehash 会导致字典中的数据分散在两个 dictht 上,因此对字典的查找操作也需要到对应的 dictht 去执行。

4. Set

在这里插入图片描述

  1. 常用命令
    在这里插入图片描述
  2. 底层实现:Intset
    当一个集合只包含整数值元素,并且这个集合的元素数量不多时, Redis i就会使用整数集合作为集合键的底层实现
    在这里插入图片描述
//每个intset结构表示一个整数集合
typedef struct intset{
    //编码方式
    uint32_t encoding;
    //集合中包含的元素数量
    uint32_t length;
    //保存元素的数组
    int8_t contents[];
} intset;

5. ZSet

Sorted Set 类似于 Set,但和 Set 相比,Sorted Set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。有点像是 Java 中 HashMap 和 TreeSet 的结合体
在这里插入图片描述

  1. 常用命令
    在这里插入图片描述

  2. 底层结构:跳表skipList

    相当于链表的多级索引
    在这里插入图片描述

  3. 压缩列表 ZipSet

听到“压缩”两个字,直观的反应就是节省内存。之所以说这种存储结构节省内存,是相较于数组的存储思路而言的。我们知道,数组要求每个元素的大小相同,如果我们要存储不同长度的字符串,那我们就需要用最大长度的字符串大小作为元素的大小(假设是20个字节)。存储小于 20 个字节长度的字符串的时候,便会浪费部分存储空间

在这里插入图片描述
数组的优势占用一片连续的空间可以很好的利用CPU缓存访问数据。如果我们想要保留这种优势,又想节省存储空间我们可以对数组进行压缩。

在这里插入图片描述
但是这样有一个问题,我们在遍历它的时候由于不知道每个元素的大小是多少,因此也就无法计算出下一个节点的具体位置。这个时候我们可以给每个节点增加一个lenght的属性。

在这里插入图片描述

二、3种特殊类型

除了 5 种基本的数据结构之外,Redis 还支持 3 种特殊的数据结构 :Bitmap、HyperLogLog、GEO

1. Bitmap

Bitmap 存储的是连续的二进制数字(0 和 1),通过 Bitmap, 只需要一个 bit 位来表示某个元素对应的值或者状态,key 就是对应元素本身 。我们知道 8 个 bit 可以组成一个 byte,所以 Bitmap 本身会极大的节省储存空间。

你可以将 Bitmap 看作是一个存储二进制数字(0 和 1)的数组,数组中每个元素的下标叫做 offset(偏移量)
在这里插入图片描述

  1. 常用命令
    在这里插入图片描述

  2. 应用场景

    需要保存状态信息(0/1 即可表示)的场景

    举例 :用户签到情况、活跃用户情况、用户行为统计(比如是否点赞过某个视频)

2. HyperLogLog

用来做基数统计,基数统计:统计一个集合中不重复元素的个数

Redis 提供的 HyperLogLog 占用空间非常非常小,只需要 12k 的空间就能存储接近2^64个不同元素

  1. 常用命令

在这里插入图片描述

  1. 应用场景

    数量量巨大(百万、千万级别以上)的计数场景

    举例 :热门网站每日/每周/每月访问 ip 数统计、热门帖子 uv 统计

3. Geospatial index

Geospatial index(地理空间索引,简称 GEO) 主要用于存储地理位置信息,基于 Sorted Set 实现。

通过 GEO 我们可以轻松实现两个位置距离的计算、获取指定位置附近的元素等功能。

  1. 常用命令

在这里插入图片描述

  1. 应用场景

    需要管理使用地理空间数据的场景

    举例:附近的人

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

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

相关文章

【CVPR轻量级网络】- 追求更高的FLOPS(FasterNet)

文章目录 题目:摘要1 介绍CNN中FLOPs的计算 2 相关工作3 PConv和FasterNet的设计3.1 偏卷积作为基本算子(PConv)3.2 PConv后接PWConv3.3 FasterNet作为通用骨干 4实验 题目: Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Netw…

Android---Jetpack之Paging

目录 Paging 组件的意思 Paging 支持的架构类型 Paging 的工作原理 PositionalDataSource PagekeyedDataSource ItemKeyedDataSource BoundaryCallback Paging 组件的意思 分页加载是在应用程序开发过程中十分常见的需求,Paging 就是 Google 为了方便 Andr…

JAVA局域网监听软件的设计与开发

网络监听软件是提供给网络安全管理人员进行安全管理的工具,可以用来监视网络的状态、数据流动情况以及网络上传输的信息,以获取有用信息。作为黑客来说,通过网络监听可以获取其所需信息(比如密码等);对黑客…

初中级Android工程师如何快速成长寻求突破

前言 写这篇文章的初衷是看到很多同学在一家公司工作了三五年,因为技术没有得到提升而随着年龄的增长导致不敢提出涨薪和跳槽找工作。希望这篇文章能够给这些还是初中级Android工程师的朋友一些启发。 快速成长 我们在向领导提出加薪申请或者是准备跳槽到更大的平…

概率机器学习笔记

1.单变量高斯混合分布 原书对结果的得出没有给出解释,我比较困惑,网上找到了一篇推导的帖子,看完就明白了。 式2.49的解释: 红框即为关键处,这是显而易见的期望,不过是条件方差的期望: 该证明的作者&…

共阳(共阴)LED数码管编码交互演示

LED数码管原理 LED数码管有两大类,一类是共阴极接法,另一类是共阳极接法,共阴极就是各段的显示字码共用一个电源的负极,是高电平点亮,共阳极就是各段的显示字码共用一个电源的正极,是低电平点亮。只要控制…

WPF教程(一)---创建一个WPF程序基础知识

1.前言: 这篇主要讲WPF的开发基础,介绍了如何使用Visual Studio 2019创建一个WPF应用程序。 首先说一下学习WPF的基础知识: 1) 要会一门.NET所支持的编程语言--例如C#。 2) 会一点“标准通用标记语言”:WPF窗体程序使用的XAML语…

字符集与字符编码的区别与演进(ASCII、GBK、UNICODE)

1 常见编码 1.1 单字节编码:ASCII ASCII使用1个字节(8个bit)来记录一组常用字符,见下表: 例如其中字母a的二进制位:1100 001 97,那么a在计算机中就可以用1100001来保存。 注意上表中其实只…

Spring入门案例--DI入门案例

入门案例思路分析 (1)要想实现依赖注入,必须要基于IOC管理Bean DI的入门案例要依赖于前面IOC的入门案例 (2)Service中使用new形式创建的Dao对象是否保留? 需要删除掉,最终要使用IOC容器中的bean对象 (3)Service中需要的Dao对象如何进入到Service中?…

1682_尝试写一个shell(做个努力的小菜鸟)

全部学习汇总: GreyZhang/bash_basic: my learning note about bash shell. (github.com) 跋:看了一下,这个可能是我大约十年前的学习笔记了,脑海中都没有多少那时候的记忆痕迹了。然而,当初的一些时间消磨的确是给今天…

Android/SELinux 添加 AVC 权限

authordaisy.skye的博客_CSDN博客-Qt,嵌入式,Linux领域博主 增加属性配置 在文件路径下增加了如下代码用于gc02m1的兼容倒置前置摄像头成像配置 //daisy if(MSM8909_SENSORS){ property_set("ro.camera.gc02m1", "1"); } /home/scooper/works…

go之基于rabbitmq的火山云服务器弹性伸缩管理程序

Author: wencoo Blog:https://wencoo.blog.csdn.net/ Date: 18/04/2023 Details:文章目录 项目背景项目功能模块实现configMq.jsonconfigECS.jsonconfigDB.json 完整代码打赏 项目背景 项目服务器不够用了,需要弹性伸缩服务器,准备使用火山的…

算法套路十——回溯法之子集型回溯

算法套路十——回溯法之子集型回溯 算法实例一:LeetCode17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不…

【Spring Boot】spring boot 项目的创建

目录 一.本地创建 二.官网创建 一:本地创建 1. 2. 3. 4. 5. 6. 选择相应的版本,并点击next 7. 8. 9. 二.官网创建 1. 点击链接进入官网 2. 3. 5. 6.

【进阶C语言】动态内存管理

前言 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于C语言进阶系列,本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数…

win10 专业版登录Microsoft账户提示:0x800704cf 错误代码——问题解决记录

win10 专业版登录Microsoft账户提示:0x800704cf 错误代码——问题解决记录 系统版本 版本 Windows 10 专业版 版本号 21H2 安装日期 ‎2021/‎5/‎7 操作系统内部版本 19044.2846 体验 Windows Feature Experience Pack 120.2212.4190.0 问题描述 曾经手动修改过…

《程序员面试金典(第6版)》面试题 10.11. 峰与谷(双指针,贪心思想)

题目描述 在一个整数数组中,“峰”是大于或等于相邻整数的元素,相应地,“谷”是小于或等于相邻整数的元素。例如,在数组{5, 8, 4, 2, 3, 4, 6}中,{8, 6}是峰, {5, 2}是谷。现在给定一个整数数组&#xff0c…

网络原理IP协议

hi,大家好,小魏又来了,我们已经认识了UDP,TCP,现在来认识一下位于网络层的协议,IP 认识IP地址 1.地址管理 2.路由选择 在之前的讲解中我们已经认识到了网络层的IP协议,负责寻路操作 IP地址(Internet Protocol Address)是指互联网协议地址&#xff0…

【Java版oj】day35年会抽奖、抄送列表

目录 一、年会抽奖 (1)原题再现 (2)问题分析 (3)完整代码 二、抄送列表 (1)原题再现 (2)问题分析 (3)完整代码 一、年会抽奖 …

C++ 命名空间 输入输出 缺省参数 引用 函数重载

在学习C之前,我们要先知道C和C是向上兼容的,也就是说,在cpp文件中既可以写入C的代码,也可以写C的代码,在日常编写代码中,经常会出现C和C混编的情况。 此博客都是在 C 的缺陷的基础之上 整理 C 中对其的优化…