Redis 7.x 系列【6】数据类型之字符串(String)

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

文章目录

    • 1. 前言
    • 2. 常用命令
      • 2.1 SET
      • 2.2 GET
      • 2.3 MSET
      • 2.4 MGET
      • 2.5 GETSET
      • 2.6 STRLEN
      • 2.7 SETEX
      • 2.8 SETNX
      • 2.9 INCR
      • 2.10 DECR
    • 3. SDS(简单动态字符串)
      • 3.1 二进制安全
      • 3.2 查询字符串长度效率高
      • 3.3 缓冲区溢出保护
      • 3.4 空间预分配
      • 3.5 惰性空间释放
    • 4. 应用场景
      • 4.1 存储常规数据
      • 4.2 计数器
      • 4.3 分布式锁

1. 前言

在官方文档中,可以看到 Redis 支持很多种数据类型,以解决不同场景下的各种问题。接下来,会详细介绍 Redis 中的各种数据类型, 主要是介绍一些常用的,包括:

  • String
  • List
  • Hash
  • Set
  • Sorted setZSet
  • Bitmap
  • HyperLogLog
  • Geospatial
  • Stream

String字符串是编程语言里最常用的数据类型,使用双引号表示。

比如JAVA

	String str="1234";

比如C语言:

    char str[] = "1234";

Redis 中, String 类型是最基本的数据类型,是二进制安全的,可以存储任意类型的数据,文本、数字、图片或者序列化的对象 。
在这里插入图片描述

注意Key的类型只能为字符串,Value的类型为字符串时,默认情况下的最大值是 512M

2. 常用命令

String 相关的所有命令:

命名描述
APPENDvalue 追加到 key 原来的值的末尾
DECRkey 中储存的数字值减一
DECRBYkey 所储存的值减去给定的减量值 ( decrement )
GET设置指定 key 的值
GETDEL获取 key 的值并删除该 key
GETEX获取 key 的值,并可选择设置其过期时间
GETRANGE返回 key 中字符串值的子字符
GETSET将给定 key 的值设为 value ,并返回 key 的旧值
INCRkey 中储存的数字值增一
INCRBYkey 所储存的值加上给定的增量值 ( increment )
INCRBYFLOATkey 所储存的值加上给定的浮点增量值 ( increment )
LCS实现了最长公共子序列算法,可用于评估字符串的相似程度
MGET获取所有(一个或多个)给定 key 的值
MSET同时设置一个或多个 key-value
MSETNX同时设置一个或多个 key-value
PSETEX以毫秒为单位设置 key 的生存时间
SET设置指定 key 的值
SETEX设置 key 的值为 value 同时将过期时间设为 seconds
SETNX只有在 key 不存在时设置 key 的值
SETRANGE从偏移量 offset 开始用 value 覆写给定 key 所储存的字符串值
STRLEN返回 key 所储存的字符串值的长度
SUBSTR返回字符串值的子字符串,由偏移量开始和结束(两者都包含在内)决定

2.1 SET

用于给指定的 Key 设置字符串值,如果 Key 已经保存了一个值,那么这个操作会直接覆盖原来的值,并且忽略原始类型。当 SET 命令执行成功后,之前设置的过期时间都将失效。

示例:

127.0.0.1:6379> SET mykey "Hello World"
OK
127.0.0.1:6379> SET mykey "Hello World" EX 60
OK

2.2 GET

用于获取指定 Key 的字符串值,如果 Key 不存在, 那么返回特殊值 nil, 如果键 Key的值不是字符串类型, 返回错误, 因为 GET 命令只能用于字符串值。

示例:

127.0.0.1:6379> GET mykey
"Hello World"
127.0.0.1:6379> GET mykey_nil
(nil)

2.3 MSET

SET 命令一样,会用新值替换旧值, MSET 是原子操作,所有 Key 的值同时设置,客户端不会看到有些 Key 值被修改,而另一些 Key 值没变。总是返回 OK ,因为 MSET 不会失败。

基本语法:

MSET key1 value1 key2 value2 .. keyN valueN 

示例:

127.0.0.1:6379> MSET key1 "Hello" key2 "World"
OK
127.0.0.1:6379> GET key1
"Hello"
127.0.0.1:6379> GET key2
"World"

2.4 MGET

用于获取所有给定 Key 的值,返回一个列表,值的类型是字符串,如果某个 Key 不存在或者值不是字符串,那么这个 Key 返回特殊值 nil

基本语法:

MGET KEY1 KEY2 .. KEYN

示例:

127.0.0.1:6379> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)

2.5 GETSET

用于给指定的 Key 设置字符串值, 并返回设置之前的旧值。如果 Key 没有旧值返回 nil,如果 Key 对应的值存在但不是字符串类型时,返回一个错误。

示例:

127.0.0.1:6379> SET mykey "Hello"
OK
127.0.0.1:6379> GETSET mykey "World"
"Hello"
127.0.0.1:6379> GET mykey
"World"

2.6 STRLEN

用于获取指定 Key 所储存的字符串值的长度,当储存的不是字符串类型时,返回错误。

基本语法:

STRLEN KEY_NAME

示例:

127.0.0.1:6379> SET mykey "Hello world"
OK
127.0.0.1:6379> STRLEN mykey
(integer) 11
127.0.0.1:6379> STRLEN mykey_nil
(integer) 0

2.7 SETEX

用于给指定的 Key 设置字符串值,并将 Key 的生存时间设置为多少秒。如果键 Key 已经存在,将覆盖已有的值。

基本语法:

SETEX key seconds value

示例:

127.0.0.1:6379> SETEX mykey 60 "Hello"
OK
127.0.0.1:6379> TTL mykey
(integer) 52
127.0.0.1:6379> GET mykey
"Hello"

2.8 SETNX

SETNXSET if Not eXists 的缩写,在指定的 Key 不存在时,设置指定的值,这种情况下等同 SET 命令,当 Key 存在时,什么也不做。

返回值为整数:

  • 1Key 存在
  • 0Key 不存在

SETNX 命令是原子性的,常用于实现分布式锁,添加成功表示获取到锁,添加失败表示未获取到锁(后续详解介绍)。

示例:

redis> SETNX mykey "Hello"
(integer) 1
redis> SETNX mykey "World"
(integer) 0
redis> GET mykey
"Hello"

2.9 INCR

用于将指定的 Key 储存的数字值增一,如果 Key 不存在,那么值会先被初始化为 0 ,然后再执行 INCR 操作,返回值为执行操作之后 Key 的值。如果值包含错误的类型,或字符串类型的值不能表示为数字,将会返回一个错误 ERR ERR hash value is not an integer

操作的值限制在 64 位(bit)有符号数字表示之内。本质上这是一个字符串操作,因为 Redis 没有专门的整数类型,储在 Key 中的字符串被转换为十进制有符号整数,在此基础上加 1 。常用于计数器、限流(后续详解介绍)。

基本语法:

 INCR KEY_NAME 

示例:

127.0.0.1:6379> SET mykey "10"
"OK"
127.0.0.1:6379> INCR mykey
(integer) 11
127.0.0.1:6379>  GET mykey
"11"

2.10 DECR

用于将指定的 Key 储存的数字值减去一,如果 Key 不存在,那么值会先被初始化为 0 ,然后再执行 DECR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,将会返回一个错误。操作的值限制在 64 位(bit)有符号数字表示之内,返回值为执行操作之后 Key 的值

基本语法:

 DECR KEY_NAME 

示例:

127.0.0.1:6379> DECR mykey
(integer) 9
127.0.0.1:6379> SET mykey "234293482390480948029348230948"
"OK"
127.0.0.1:6379>DECR mykey
ERR ERR value is not an integer or out of range

3. SDS(简单动态字符串)

SDSSimple Dynamic String 的首字母缩写,翻译为简单的动态字符串,是 Redis 自定义的一种表示字符串的特殊数据结构。相较于传统的C语言字符串,SDS 具有更多的功能和更高的性能,当前也会占用更多的内存。

Redis 3.2 之前的版本:

struct sdshdr {int len; // 记录buf数组中已使用字节的数量,即字符串的实际长度int free; // 存储剩余(空闲)的空间char buf[]; // 存储实际数据
};

Redis 3.2 之后的版本,SDS 变成了 5 种数据结构,不同类型的存储空间大小不一样:

/* Note: sdshdr5 is never used, we just access the flags byte directly.* However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; // 已用空间的长度,占 4 个字节,不包括 ‘\0’;uint8_t alloc; // 实际分配长度,占 4 个字节,不包括 ‘\0’;unsigned char flags; // 标记当前 buf[] 类型( sdshdr8/16/32/64)char buf[]; // 存储实际数据
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* used */uint64_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};

相比于C语言字符串,SDS 有以下优点:

  • 二进制安全
  • 查询字符串长度效率高
  • 缓冲区溢出保护
  • 空间预分配
  • 惰性空间释放

3.1 二进制安全

C 语言中,用字符 \0 表示字符串的结束,如果字符串中本身就有 \0 字符,字符串就会被截断,即非二进制安全,例如 hello \0 world 会被截断解析为 hello

SDS 不受 \0 字符影响,能够准确存储任意二进制数据,因为它基于 len 属性而非遇到 \0 来判断字符串的结束位置。

3.2 查询字符串长度效率高

C 语言中,获取一个字符串长度时,需对整个字符串进行遍历,直至遇到结束符号。在高并发场景下频繁遍历字符串,势必会造成性能瓶颈。

SDS 中于 len 属性记录了字符串的长度,可以直接通过 STRLEN 命令获取长度即可。

3.3 缓冲区溢出保护

C 语言中,字符串本身不记录可用空间大小,在进行字符串拼接等操作时,如果没有检查就可能会导致缓冲区溢出。

SDS 中于 free 属性记录了额外未使用的空间大小,每次进行字符串操作前都会检查剩余空间是否足够,不足时会自动扩容,有效避免了缓冲区溢出问题。

3.4 空间预分配

C 语言中,每次修改字符串长度(增加或减少)时,通常需要重新分配内存,这可能导致频繁的内存操作。

SDS 优化了字符串增长操作,当修改字符串并需对 SDS 的空间进行扩展时,不仅会为 SDS分配修改所必要的空间,还会分配额外的未使用空间(free属性),下次再修改就先检查未使用空间free是否满足,满足则不用在扩展空间。有效的减少字符串连续增长操作,减少所产生的内存重分配次数。

3.5 惰性空间释放

惰性空间释放策略则用于优化 SDS 字符串缩短操作,当缩短 SDS 字符串后,并不会立即执行内存重分配来回收多余的空间,而是用 free 属性将这些空间记录下来,如果后续有增长操作,则可直接使用。

4. 应用场景

4.1 存储常规数据

String 可以存储任意类型的数据,文本、数字、图片或者序列化的对象 。

常用实际场景:

  • 图形、短信验证码
  • 令牌

例如,存储短信验证码并设置过期时间为 60 秒:

localhost:0>SET 13688889999 80906 EX 60
"OK"
localhost:0>GET 13688889999
"80906"

4.2 计数器

INCR 用于将指定的 Key 储存的数字值增一, DECR 用于将指定的 Key 储存的数字值减去一。

常用实际场景:

  • 阅读数
  • 点赞
  • 分布式ID
  • 网站访问量
  • 记录接口访问次数,实现防止重复提交、简单限流

例如,使用 INCR 记录网站每日访问量:

localhost:0>SET web_views:20240617 0
"OK"
localhost:0>INCR web_views:20240617
"1"
localhost:0>GET web_views:20240617
"1"

4.3 分布式锁

SETNX 命令是原子性的,常用于实现分布式锁,添加成功表示获取到锁,添加失败表示未获取到锁(后续详解介绍)。

例如,执行 SETNX 添加锁,返回 1 表示成功获取到锁:

localhost:0>SETNX my_lock yes
"1"

其他线程执行SETNX,返回 0 表示获取锁失败:

localhost:0>SETNX my_lock yes
"0"

执行完成后,删除锁,其他线程再次获取则成功:

localhost:0>DEL my_lock
"1"
localhost:0>SETNX my_lock yes
"1"

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

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

相关文章

南昌高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

南昌高校大学智能制造实验室,作为该地区乃至全国智能制造领域的重要研究和教学基地,一直致力于探索和创新智能制造技术。近日,该实验室的数字孪生可视化系统平台建设项目成功通过了验收,标志着其在数字孪生技术领域取得了重大突破…

滑动窗口2

1. 水果成篮(904) 题目描述: 算法原理: 根据题目意思,friuts表示第i棵树上的水果种类,然后我们有两个篮子去在这些树上去采水果,但是有限制就是一个篮子里就只能装一种水果,也就是…

RK35x8通过TFTP下载内核到开发板

对于有网线接口的RK35X8开发板,调试时候,可以通过网线下载内核镜像和设备树到开发板,不用每次修改驱动都要重新打开下载工具,进入下载模式。通过TFTP可以大大提高调试效率。 在ubuntu安装TFTP服务 安装tftp服务器 sudo apt-get…

【笔记】Spring Cloud Gateway 实现 gRPC 代理

Spring Cloud Gateway 在 3.1.x 版本中增加了针对 gRPC 的网关代理功能支持,本片文章描述一下如何实现相关支持.本文主要基于 Spring Cloud Gateway 的 官方文档 进行一个实践练习。有兴趣的可以翻看官方文档。 由于 Grpc 是基于 HTTP2 协议进行传输的,因此 Srping …

鸿蒙 如何 url decode

在 TypeScript 和 JavaScript 中进行 URL 编码的最简单方式是使用内置的 global 函数 encodeURIComponent()。以下是一个示例: let url "https://example.com/?name测试&job开发者"; let encodedURL encodeURIComponent(url); console.log(encode…

【RAG】FoRAG:面向网络增强型长形式问答的事实性优化RAG

一、解决问题 在基于网络的长形式问答(Web-enhanced Long-form Question Answering, LFQA)任务中,现有RAG在生成答案时存在的问题: 事实性不足:研究表明,现有系统生成的答案中只有大约一半的陈述能够完全得…

Qt开发笔记:Qt3D三维开发笔记(一):Qt3D三维开发基础概念介绍

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/140059315 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、O…

来自Claude官方的提示词库,支持中文!建议收藏!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,所以创建了“AI信息Gap”这个公众号,专注于分享AI全维度知识,包括但不限于AI科普,AI工具测评,AI效率提升,AI行业洞察。关注我,AI之…

多元时间序列分析——VAR(向量自回归模型)

VAR模型主要是考察多个变量之间的动态互动关系,从而解释各种经济冲击对经济变量形成的动态影响。这种动态关系可通过格兰杰因果关系、脉冲响应以及方差分解来进一步明确和可视化。VAR模型主要研究内生变量之间的关系,内生变量就是参与模型并由模型体系内…

通天星CMSV6车载监控平台CompanyList信息泄露漏洞

1 漏洞描述 通天星CMSV6车载视频监控平台是东莞市通天星软件科技有限公司研发的监控平台,通天星CMSV6产品覆盖车载录像机、单兵录像机、网络监控摄像机、行驶记录仪等产品的视频综合平台。通天星科技应用于公交车车载、校车车载、大巴车车载、物流车载、油品运输车载、警车车…

推荐一款程序员的搞钱神器

你是不是经常为开发环境的搭建而头疼?有没有遇到过因为接口开发而焦头烂额的情况?作为一名程序员,特别是独立开发者,这些问题是不是常常让你觉得心力交瘁?别担心,现在有一个神器,能让你摆脱这些…

2024HVV最新POC/EXP,目前有8000+个POC/EXP

点击"仙网攻城狮”关注我们哦~ 不当想研发的渗透人不是好运维 让我们每天进步一点点 简介 都是网上收集的POC和EXP,最新收集时间是2024年五月,需要的自取。 表里没有的可以翻翻之前的文章,资源比较零散没有整合起来。 文件链接&#xff…

阿里云智能编程助手的安装使用

https://help.aliyun.com/document_detail/2590613.html 通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力&a…

洞察数据资产的奥秘:深入剖析数据资产在企业运营中的核心作用,提出一套全面、系统的数据资产解决方案,帮助企业实现数据资产的最大化利用和增值

一、引言 在数字化浪潮汹涌的今天,数据已成为企业最宝贵的资产之一。数据资产不仅记录了企业的历史运营轨迹,更蕴含着指导未来决策的智慧。然而,如何有效管理、利用这些数据资产,使其转化为企业的竞争优势和利润增长点&#xff0…

python--基础篇--正则表达式--py脚本--题目解答

文章目录 验证输入用户名和QQ号是否有效并给出对应的提示信息从一段文字中提取出国内手机号码替换字符串中的不良内容拆分长字符串 验证输入用户名和QQ号是否有效并给出对应的提示信息 """ 验证输入用户名和QQ号是否有效并给出对应的提示信息要求:用…

扎克伯格抨击闭源人工智能竞争对手试图“创造上帝”

Meta 首席执行官马克-扎克伯格(Mark Zuckerberg)在周四发表的一篇访谈中谈到了他对人工智能未来的看法,他深信"不会只有一种人工智能"。扎克伯格强调了开源的价值,即把人工智能工具交到许多人手中,他还不忘贬…

抖音微短剧小程序源码搭建:实现巨量广告数据高效回传

在数字化营销日益盛行的今天,抖音微短剧小程序已成为品牌与观众互动的新渠道。这些短小精悍的剧目不仅能迅速抓住用户的注意力,还能有效提升品牌的知名度和用户黏性。然而,想要充分利用这一营销工具,关键在于如何高效地追踪广告数…

springboot中使用springboot cache

前言&#xff1a;SpringBoot中使用Cache缓存可以提高对缓存的开发效率 此图片是SpringBootCache常用注解 Springboot Cache中常用注解 第一步&#xff1a;引入依赖 <!--缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId…

STM32第十一课:ADC采集光照

文章目录 需求一、ADC概要二、实现流程1.开时钟&#xff0c;分频&#xff0c;配IO2.配置ADC工作模式3.配置通道4.复位校准5.数值的获取 三、需求的实现总结 需求 通过ADC转换实现光照亮度的数字化测量&#xff0c;最后将实时测量的结果打印在串口上。 一、ADC概要 ADC全称是A…

手机数据恢复篇:如何在Android手机上查找和恢复已删除的文件

移动设备中的回收站已成为 Android 用户的一项基本功能&#xff0c;它提供了防止意外删除的安全网。与计算机一样&#xff0c;移动回收站会临时存储已删除的文件&#xff0c;允许用户在需要时检索它们。此功能在当今的数字时代特别有用&#xff0c;因为只需轻轻一按&#xff0c…