Redis数据结构之String

news2024/11/18 20:42:28

String 类型是 Redis 的最基本的数据类型,一个 key 对应一个 value,可以理解成与Memcached一模一样的类型。

String 类型是二进制安全的,意思是 Redis 的 String 可以包含任何数据,比如图片或者序列化的对象,一个 Redis 中字符串 value 最多可以是 512M。并且的存储是动态的(意味着可以随时修改它本身的值),每次分配内存时会高出实际字符串的 length,这样采用预分配冗余空间方式来减少内存的频繁分配。


文章目录

        • 1、String数据类型
          • 1.1、String类型简介
          • 1.2、String应用场景
        • 2、String底层结构
          • 2.1、SDS简单动态字符串结构
          • 2.2、SDS简单动态字符串优点
        • 3、String常用命令
          • 3.1、设定/获取操作
          • 3.2、自增/自减操作
          • 3.3、追加字符串
          • 3.4、删除字符串
          • 3.5、截取字符串
          • 3.6、替换字符串
          • 3.7、分布式锁设置
          • 3.8、设置过期时间
          • 3.9、批量操作设置
          • 3.10、获取字符串长度


1、String数据类型

1.1、String类型简介

String 类型是 Redis 的最基本的数据类型,一个 key 对应一个 value,可以理解成与Memcached一模一样的类型。

String 类型是二进制安全的,意思是 Redis 的 String 可以包含任何数据,比如图片或者序列化的对象,一个 Redis 中字符串 value 最多可以是 512M。并且的存储是动态的(意味着可以随时修改它本身的值),每次分配内存时会高出实际字符串的 length,这样采用预分配冗余空间方式来减少内存的频繁分配。

1.2、String应用场景

String 使用场景一般是存储简单的键值类型。比如用户信息,登录信息,配置信息等。还有一种用得比较多的是 string 的 “incr/decr” 操作,即"自减/自增"操作。调用它是原子性的,无论调用多少次,都一一计算成功,例如需要增减库存的操作。

应用场景:

  1. 缓存基础数据:例如缓存登录用户的基本的缓存数据,但是建议使用 Hash 缓存;
  2. 计数器:浏览量、点击数等。利用 string 的 “incr/decr” 操作,即"自减/自增"操作,并且它是原子性的;
  3. 限制请求次数:也是利用 “incr” 方法,以访问者的 ip 和其他信息作为 key,访问一次增加一次计数,超过次数则返回 false;
  4. 分布式共享 Session:因为 Redis 是分布式的独立服务,可以在多个应用之间共享,所以可以用作分布式 Session 等场景;
  5. 分布式锁:SET 命令有个 NX 参数可以实现「key不存在才插入」,可以用它来实现分布式锁。

2、String底层结构

2.1、SDS简单动态字符串结构

Redis 使用 SDS 简单动态字符串(Simple Dynamic String,SDS)来表示字符串,Redis 中字符串类型包含的数据结构有:整数(R_INT)、字符串(R_RAW)。

我们以字符串为例子,常规的字符串,如 “Brand”,如果要获取他的长度,需要从头开始遍历,直至遇到 ‘\0’ 空字符代表结尾,如 C 字符串:

C 字符串结构与 SDS 字符串结构对比图参照如下:

image-20230813124658755

结合上图来看,其中:

属性说明
“Free”记录 Buf 数组中未使用字节的长度
“Len”记录 Buf 数组中已使用字节的长度,等于 “Buf[]” 中字符串的长度
“Buf[]”字节数组,用于保存字符串,最后一个字节则保存了空字符 ‘\0’,代表结尾。
2.2、SDS简单动态字符串优点

比起 C 字符串,SDS 具有以下优点:

  1. 时间方面:SDS 获取字符串长度时间复杂度为 O(1) ,C 字符串不记录自身长度,获取 C 字符串长度时必须遍历整个字符串计数得到,复杂度是 O(N),SDS 字符串自身记录维护 “Len” 长度属性,获得 SDS 字符串长度的复杂度是 O(1);

  2. 空间方面-空间预分配操作:SDS 被修改后,程序不仅会为 SDS 分配所需要的空间,还会分配额外的未使用空间。这样,Redis 可以减少连续执行字符串增长操作所需的内存重分配次数;

  3. 空间方面-杜绝缓冲区溢出:C 字符串不记录长度,由于两个 C 字符串在内存存储上紧邻,在执行字符串拼接 strcat 时,如果不提前分配足够空间,很可能发生修改 s1 的数据溢出到 s2 所在的空间中(缓冲区溢出)。SDS 杜绝了缓冲区溢出问题,它记录了长度,当修改 SDS 字符串之前,API 都会检查 SDS 的空间是否满足修改的要求,不满足 API 会自动进行空间扩展;

    具体分配未使用空间如下 2 种方式:

    • 如修改后长度 “Len” 小于 1MB,就分配和 “Len” 属性相同大小的未使用空间:Free=Len

    • 如修改后长度 “Len” 大于等于 1MB,就分配 1M 的未使用空间:Free=1MB

  4. 空间方面-惰性空间的释放:SDS 避免了缩短字符串时所需的内存重分配操作,并为将来可能有的增长操作提供了优化。当 SDS 做缩短操作,不会立刻使用内存重分配来收回缩短后多出来的字节,而是保持在 free 属性里。将来如果需要 append 操作,则直接使用 “Free” 中未使用的空间,减少了内存的分配步骤。另外,SDS 也提供了 API 手动进行释放 SDS 未使用空间,避免惰性释放策略会造成内存浪费;

  5. 二进制安全:二进制安全:C 字符串的字符必须符合某种编码,除结尾空字符以外,字符串内部不允许有空字符串,存储有局限性。而在 Redis 中,不仅可以存储 String 类型的数据,也可能存储一些二进制数据。二进制数据并不是规则的字符串格式,其中会包含一些特殊的字符如 ‘\0’。在 C 中遇到 ‘\0’ 则表示字符串的结束,但 SDS 不是,它是以 “Len” 长度标识结尾;

  6. 兼容 C 字符串函数:SDS 虽然不仅二进制安全的,还是秉承 C 字符串以空字符结尾的特性,很多函数与 C 字符串一致不需要重写。


3、String常用命令

3.1、设定/获取操作

设定/获取 Key 值:

SET key value					# 设置指定 key 的值:
GET key								# 获取指定 key 的值:

image-20230819233407969

3.2、自增/自减操作

自减/自增 Key 值:

INCR key							# 自增
DECR key							# 自减

String 类型除了可以存字符串也可以是数字。注意这里得是数字才可以进行

image-20230819234729301

如果要带步长:

INCRBY key	num				# 自增
DECRBY key	num				# 自减

image-20230819234934419

3.3、追加字符串

使用 append 追加字符串:

APPEND key addvalue

append 命令后但会当前 string 长度。

image-20230819233702727

3.4、删除字符串

使用 del 删除字符串:

DEL key
DEL key1 key2 key3

image-20230819235218967

3.5、截取字符串

使用 getrange 截取字符串:

getrange key start end
getrange key 0 -1						# 查询全部

image-20230819235823254

3.6、替换字符串

使用 setrange 替换字符串::

setrange key num value

image-20230820000105855

3.7、分布式锁设置

分布锁设置,只有在 key 不存在时设置 key 的值:

SETNX key value 	

image-20230820000733308

3.8、设置过期时间

设置指定 key 的值,并将 key 的过期时间设为 seconds 秒:

SETEX key seconds value

image-20230820001035365

3.9、批量操作设置

一次性设置多个:

MSET k1 v1 k2 v2 k3 v3

一次性获取多个:

MGET k1 k2 k3

image-20230820001549588

一次性设置多个(事务),只要有一个失败,则都不成功:

MSETNX k1 v1 k2 v2 k3 v3

image-20230820001812549

3.10、获取字符串长度

使用 strlen 获取字符串长度:

STRLEN key

image-20230819234040304

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

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

相关文章

【Redis从头学-6】Redis中的Hash数据类型实战场景之购物车

🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 📖所属专栏:Re…

如何使用媒体查询(media query)来适配不同设备上的样式?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用媒体查询适配不同设备上的样式⭐ 基本语法⭐ 示例⭐ 常见的媒体特性⭐ 创建响应式布局⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来…

(2)、将SpringCache扩展功能封装为starter

(2)、将SpringCache扩展功能封装为starter 1、准备工作 前面我们写了一个common-cache模块,尽可能的将自定义的RedisConnectionFactory, RedisTemplate, RedisCacheManager等Bean封装了起来。 就是为了方便我们将其封装为一个Starter。 我们这里直接《SpringCache+Redis实…

LLM 生成式配置的推理参数温度 top k tokens等 Generative configuration inference parameters

在这个视频中,你将了解一些方法和相关的配置参数,这些参数可以用来影响模型在下一个词生成时的最终决策方式。如果你在Hugging Face网站或AWS的游乐场中使用过LLMs,你可能已经看到了这些控制选项,用来调整LLM的行为。每个模型都暴…

Communication Channels

沟通渠道 n * (n - 1) / 2 你1 相关方3 4 4 * 3 / 2 6 你1 相关方3 相关方1 5 5 * 4 / 2 10 人越多,沟通渠道越多,沟通成本理论越高

Qt文件系统操作和文件的读写

一、文件操作类概述 QIODevice:所有输入输出设备的基础类 QFile:用于文件操作和文件数据读写的类QSaveFile:用于安全保存文件的类QTemporaryFile:用于创建临时文件的类QTcpSocket和QUdpSocket:分别实现了TCP和UDP的类…

CSSCI、北核期刊投稿指南(2023年更新)

该数据为经管类的期刊投稿指南,包含发表难度,文章数量,影响因子,用户评价等指标。共5份文件,分别为国内所有期刊信息库、投稿指南(CSSCI版本、CSSCI扩展版本、北大核刊版本、建议期刊版本) 一、…

Risk Probability

风险概率计算 sum p1 * v1 p2 * v2 p3 * v3 ... pn * vn

memmove的实现与使用

memmove与memcpy相比,可以实现同一数组的赋值 memmove要点 1.和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。 2.如果源空间和目标空间出现重叠,就得使用memmove函数处理。 函数实现 void* my_memmove(void* dest, void* sor…

【无监督】5、DINO | 使用自蒸馏和 transformer 来释放自监督学习的超能力(ICCV2021)

文章目录 一、背景二、相关工作三、方法四、效果 论文:Emerging Properties in Self-Supervised Vision Transformers 代码:https://github.com/facebookresearch/dino 出处:ICCV2021 | FAIR DINO: self-DIstillation with NO …

Ubuntu服务器service版本初始化

下载 下载路径 官网:https://cn.ubuntu.com/ 下载路径:https://cn.ubuntu.com/download 服务器:https://cn.ubuntu.com/download/server/step1 点击下载(22.04.3):https://cn.ubuntu.com/download/server…

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)一(112)

需求&#xff1a;&#xff1a; 有一个List<Map<String.Object>>,存储了某年某月的数据&#xff0c; 数据是根据用户查询条件进行显示的&#xff1b;所以查询的数据是动态的&#xff1b;需按月份统计每个年月数据出现的次数&#xff0c;并且按照月份排序&#xff1…

Oracle19c-补丁升级报错合集(一)

前言: 本文主要介绍Oracle19c补丁升级遇到的问题&#xff0c;涉及安装补丁prepatch步骤&#xff0c;apply应用报错以及datapatch -verbose数据字典更新报错 问题一: 在执行补丁rootcrs.sh -prepatch操作时&#xff0c;发生执行检查命令cluutil -chkshare报错 CLSRSC-180: An …

春秋云镜 CVE-2019-9042

春秋云镜 CVE-2019-9042 Sitemagic CMS v4.4 任意文件上传漏洞 靶标介绍 Sitemagic CMS v4.4 index.php?SMExtSMFiles 存在任意文件上传漏洞&#xff0c;攻击者可上传恶意代码执行系统命令。 启动场景 漏洞利用 login进入登陆界面admin/admin 访问http://eci-2zebi1tekpr…

什么是BEM命名规范?为什么要使用BEM命名规范?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ BEM命名规范⭐ 为什么使用BEM命名规范&#xff1f;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为…

ROS_LINUX学习笔记=2=

B站ros入门教程 rqt_robot_steering 控制小乌龟 在index ros .rog中查找相关的包&#xff1a;rosindex 下图是rqt_robot_steering的简介 其中可以查看github源码地址 website可以查看效果图 下载相关的包 sudo apt install ros-kinetic-rqt-robot-steering roscore打开ros核…

C++入门知识点——解决C语言不足

&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️ &#x1f4a5;个人主页&#xff1a;&#x1f525;&#x1f525;&#x1f525;大魔王&#x1f525;&#x1f525;&#x1f525; &#x1f4a5;代码仓库&#xff1a;&#x1f525;&#x1f525;魔…

D. Anton and School - 2

范德蒙德恒等式 考虑统计每一个右括号位置的贡献&#xff0c;也就是每个右括号作为右边起点的贡献 其中i0的时候&#xff0c;r-1<r-0,故i0时贡献为0&#xff0c;直接套用恒等式不会有影响 #include <bits/stdc.h> using namespace std; typedef long long int ll; # d…

JAVA入坑之高级文件处理

一、图片文件简介及解析 1.1图形图像基础概念 1.2JAVA图形图像关键类 1.3图形的基本操作 package org.example;import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; imp…