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,一经查实,立即删除!

相关文章

全方位对比PostgreSQL和MySQL

目录 引言 技术架构与设计哲学 起源与发展 数据库引擎 PostgreSQL与MySQL:SQL语法与特性对比概览 PostgreSQL与MySQL高级特性对比:数据类型与事务处理能力 数据类型与功能特性 PostgreSQL与MySQL性能与可扩展性对比 PostgreSQL与MySQL性能与可扩…

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

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

Trick :带 pop 的 STL 结构化绑定时不要用 auto

题目描述 给一个 n m n\times m nm 矩阵迷宫, 第 i i i 行第 j j j 列的值为 c i , j c_{i,j} ci,j​ , L H LH LH 在迷宫中迷路了,他需要你的帮助。 L H LH LH 当前在 ( 1 , 1 ) (1,1) (1,1) 的位置,出口在 ( n , m ) (n…

安卓应用内通信的核心-Handler

Handler Handler是安卓应用内通信的核心。 Handler相关的类简介 Handler机制整体可以看作一个传送带。 Looper 传送带的轮子。Handler 传送带上货物的入口和出口。Message 传送带上的货物。MessageQueue 传送带的皮带。 基础知识 一个Thread只有一个Looper,一…

滑动窗口2

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

矩阵运算在数据分析中的应用

矩阵运算在数据分析中的应用 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 矩阵运算作为数学和计算机科学中的重要概念,在数据分析和科学计算中发…

elasticsearch源码分析-03选举集群状态

选举集群状态 es中存储的数据有一下几种,state元数据、lucene索引文件、translog事务日志 元数据信息可以分为: 集群层面的元信息-对应着metaData数据结构,主要是clusterUUid、settings、templates等索引层面的元信息-对应着indexMetaData数…

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

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

【面试系列】前端开发工程师高频面试题及详细解答

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…

Python商务数据分析知识专栏(二)——Python数据分析基础

Python商务数据分析知识专栏(二)——Python数据分析基础 一、Python数据分析概述二、Numpy数值计算基础专栏二(Python数据分析基础)的总结 与 专栏三(Python数据分析的应用)开端 一、Python数据分析概述 二…

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

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

深度学习之Transformer模型的Vision Transformer(ViT)和Swin Transformer

Transformer 模型最初由 Vaswani 等人在 2017 年提出,是一种基于自注意力机制的深度学习模型。它在自然语言处理(NLP)领域取得了巨大成功,并且也逐渐被应用到计算机视觉任务中。以下是两种在计算机视觉领域中非常重要的 Transformer 模型:Vision Transformer(ViT)和 Swi…

git 个人常见错误备注

问题1:all conflict fixed but you are still merging。。。。。 如果你已经解决了所有冲突,但 Git 仍然提示你正在进行合并,可能是因为你还没有完成合并过程。以下是详细步骤,确保你正确完成合并并提交更改: 确认所…

Tongsuo(铜锁)项目介绍 - 实现国密SSL协议

文章介绍 铜锁(Tongsuo)是一个提供现代密码学算法和安全通信协议的开源基础密码库,为存储、网络、密钥管理、隐私计算、区块链等诸多业务场景提供底层的密码学基础能力,实现数据在传输、使用、存储等过程中的私密性、完整性和可认证性,为数据生命周期中的隐私和安全提供保…

鸿蒙 如何 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…

汇编语言基础教程

汇编语言基础教程 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨汇编语言的基础知识和应用,帮助大家理解汇编语言在计算机编程中…

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

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

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

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