Redis 数据类型 String 字符串

news2025/2/13 1:31:52

Redis 中的 String 数据类型 是最基础且使用最广泛的数据类型之一。它本质上是一个字节序列,可以存储各种类型的数据,如字符串、整数、浮点数等,其字符串类型的值包含⼀般格式的字符串或者类似 JSON、XML 格式的字符串;还可以存储⼆进制流数据,例如图⽚、⾳频、视频等,不过⼀个字符串的最⼤值不能超过 512 MB。String 数据类型支持多种操作,包括设置、获取、更新、追加等。

String 数据类型的特点

  • 存储任意数据:Redis 的 String 数据类型可以存储任意类型的数据,包括文本、数字等。

  • 原子操作:所有对 String 的操作都是原子性的,即在执行过程中不会被其他操作打断。

  • 内存优化:Redis 会根据 String 的大小和内容自动选择合适的内部编码方式,以优化内存使用。

String 的内部编码

Redis 的 String 数据类型有三种内部编码方式:

  1. int:当字符串值可以表示为整数时,使用 8 字节的长整型编码。

  2. embstr:当字符串长度较短(小于等于 39 字节)时,使用嵌入式字符串编码。

  3. raw:当字符串长度较长时,使用原始字符串编码。

由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的,所以 Redis 是不处理字符集编码问题的,客⼾端传⼊的命令中使⽤的是什么字符集编码,就存储什么字符集编码。有时候我们存储的值为中文汉字时,读取时会变成乱码,这时我们可以使用如下命令重新启动客户端:
redis-cli --raw

使用 --raw 参数可以让 redis-cli原始二进制形式输出数据,而不是进行格式化,这对于处理二进制数据或非 ASCII 字符(如中文)非常有用。

常见命令

设置和获取键值

SET

将 string 类型的 value 设置到 key 中。如果 key 之前存在则覆盖,⽆论原来的数据类型是什么,之前关于此 key 的 TTL 也全部失效。
语法:
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
时间复杂度:O(1)
选项:
  • SET 命令⽀持多种选项来影响它的⾏为:
  • EX seconds⸺使⽤秒作为单位设置 key 的过期时间。
  • PX milliseconds⸺使⽤毫秒作为单位设置 key 的过期时间。
  • NX ⸺只在 key 不存在时才进⾏设置,即如果 key 之前已经存在,设置不执⾏。
  • XX ⸺只在 key 存在时才进⾏设置,即如果 key 之前不存在,设置不执⾏。
注意:带选项的 SET 命令可以被 SETNX SETEX PSETEX 等命令代替。
返回值:
  • 如果设置成功,返回 OK。
  • 如果由于 SET 指定了 NX 或者 XX 但条件不满⾜,SET 不会执⾏,并返回 (nil)。

示例:

MSET

⼀次性设置多个 key 的值。
语法:
MSET key value [key value ...]
时间复杂度:O(N) N 是 key 数量
返回值:永远是 OK
⽰例:

GET

获取 key 对应的 value。如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错。
语法:
GET key
时间复杂度:O(1)
返回值:key 对应的 value,或者 nil 当 key 不存在。

MGET

⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil。
语法:
MGET key [key ...]
时间复杂度:O(N) N 是 key 数量
返回值:对应 value 的列表
⽰例:

使⽤ mget / mset 由于只进行一次 IO 就可以完成多条命令,可以有效地减少了⽹络时间,所以性能相较更⾼。假设⽹络耗时 1 毫秒,命令执⾏时间耗时 0.1 毫秒,则执⾏时间如表所⽰。

操作时间
1000 次 get1000 x 1 + 1000 x 0.1 = 1100 毫秒
1 次 mget 1000 个键1 x 1 + 1000 x 0.1 = 101 毫秒
学会使⽤批量操作,可以有效提⾼业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是⽆节制的,否则可能造成单⼀命令执⾏时间过⻓,导致 Redis 阻塞。

APPEND

如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key 不存在,则效果等同于 SET 命令。
语法:
APPEND KEY VALUE
时间复杂度:O(1)
返回值:追加完成之后 string 的⻓度。
⽰例:

GETRANGE

返回 key 对应的 string 的⼦串,由 start 和 end 确定(左闭右闭),可以使⽤负数表⽰倒数。-1 代表倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据 string 的⻓度调整成正确的值。
语法:
GETRANGE key start end
时间复杂度:O(N). N 为 [start, end] 区间的⻓度. 由于 string 通常⽐较短, 可以视为是 O(1)
返回值:string 类型的⼦串
⽰例:

SETRANGE

覆盖字符串的⼀部分,从指定的偏移开始。
语法:
SETRANGE key offset value
时间复杂度:O(N), N 为 value 的⻓度. 由于⼀般给的 value ⽐较短, 通常视为 O(1).
返回值:替换后的 string 的⻓度。
⽰例:

STRLEN

获取 key 对应的 string 的⻓度。当 key 存放的类似不是 string 时,报错。
语法:
STRLEN key
时间复杂度:O(1)
返回值:string 的⻓度。或者当 key 不存在时,返回 0。
⽰例:

计数命令

INCR

将 key 对应的 string 表⽰的数字加⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
INCR key
时间复杂度:O(1)
返回值:integer 类型的加完后的数值。
⽰例:

INCRBY

将 key 对应的 string 表⽰的数字加上对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
INCRBY key decrement
时间复杂度:O(1)
返回值:integer 类型的加完后的数值。
⽰例:

DECR

将 key 对应的 string 表⽰的数字减⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
DECR key
时间复杂度:O(1)
返回值:integer 类型的减完后的数值。
⽰例:

DECYBY

将 key 对应的 string 表⽰的数字减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
DECRBY key decrement
时间复杂度:O(1)
返回值:integer 类型的减完后的数值。
⽰例:

INCRBYFLOAT

将 key 对应的 string 表⽰的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的不是 string,或者不是⼀个浮点数,则报错。允许采⽤科学计数法表⽰浮点数。
语法:
INCRBYFLOAT key increment
时间复杂度:O(1)
返回值:加/减完后的数值。
⽰例:

典型使⽤场景

缓存(Cache)功能

Redis 作为缓冲层,存储热点数据(如频繁访问的数据), MySQL 作为存储层,作为持久化存储层,存储所有数据, 绝⼤部分请求的数据都是从 Redis 中获取,因为Redis 是基于内存的键值存储,读取速度极快,能够快速响应用户的请求 。由于 Redis 具有⽀撑⾼并发的特性,所以缓存通常能起到加速读写和降低后端压⼒的作⽤。

以下是 Redis 和 MySQL 之间的数据交互流程:

  1. 读取数据

    • 应用程序首先尝试从 Redis 中读取数据。

    • 如果 Redis 中存在数据(缓存命中),直接返回数据。

    • 如果 Redis 中不存在数据(缓存未命中),应用程序从 MySQL 中读取数据,然后将数据写入 Redis 缓存,最后返回数据给用户。

  2. 写入数据

    • 应用程序将数据写入 MySQL。

    • 写入 MySQL 后,更新 Redis 缓存,以保证数据的一致性。

    • 如果数据更新频繁,可以使用失效策略,如设置缓存的过期时间,让 Redis 在一定时间后自动失效缓存。

下⾯的伪代码模拟业务数据访问过程:
  • 假设业务是根据⽤⼾ uid 获取⽤⼾信息,⾸先从 Redis 获取⽤⼾信息,我们假设⽤⼾信息保存在 "user:info:<uid>" 对应的键中:
UserInfo getUserInfo(long uid) {
// 根据 uid 得到 Redis 的键
string key = "user:info:" + uid;
// 尝试从 Redis 中获取对应的值
string value = Redis 执⾏命令:get key;
// 如果缓存命中(hit)
if (value != null) {
 // 假设我们的⽤⼾信息按照 JSON 格式存储
 UserInfo userInfo = JSON 反序列化(value);
 return userInfo;
}
  • 如果没有从 Redis 中得到⽤⼾信息,及缓存 miss,则进⼀步从 MySQL 中获取对应的信息,随后写⼊缓存并返回:
// 如果缓存未命中(miss)
if (value == null) {
 // 从数据库中,根据 uid 获取⽤⼾信息
 UserInfo userInfo = MySQL 执⾏ SQL:select * from user_info where uid = <uid>
 // 如果表中没有 uid 对应的⽤⼾信息
 if (userInfo == null) {
 响应 404
 return null;
 }
 // 将⽤⼾信息序列化成 JSON 格式
 String value = JSON 序列化(userInfo);
 // 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)
 Redis 执⾏命令:set key value ex 3600 
 // 返回⽤⼾信息
 return userInfo;
}
通过增加缓存功能,在理想情况下,每个⽤⼾信息,⼀个⼩时期间只会有⼀次 MySQL 查询,极⼤地提升了查询效率,也降低了 MySQL 的访问数。
与 MySQL 等关系型数据库不同的是,Redis 没有表、字段这种命名空间,⽽且也没有对键名有强制要求(除了不能使⽤⼀些特殊字符)。但设计合理的键名,有利于防⽌键冲突和项⽬的可维护性,⽐较推荐的⽅式是使⽤ "业务名:对象名:唯⼀标识:属性" 作为键名。例如 MySQL 的数据库名为 vs,⽤⼾表名为 user_info,那么对应的键可以使⽤"vs:user_info:6379:name" 来表⽰。

计数(Counter)功能

许多应⽤都会使⽤ Redis 作为计数的基础⼯具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。例如视频⽹站的视频播放次数可以使⽤ Redis 来完成:⽤⼾每播放⼀次视频,相应的视频播放数就会⾃增 1。
// 在 Redis 中统计某视频的播放次数
long incrVideoCounter(long vid) {
key = "video:" + vid;
long count = Redis 执⾏命令:incr key
return counter;
}

共享会话(Session)

⼀个分布式 Web 服务将⽤⼾的 Session 信息(例如⽤⼾登录信息)保存在各⾃的服务器中,但这样会造成⼀个问题:出于负载均衡的考虑,分布式服务会将⽤⼾的访问请求均衡到不同的服务器上,并且通常⽆法保证⽤⼾每次请求都会被均衡到同⼀台服务器上,这样当⽤⼾刷新⼀次访问是可能会发现需要重新登录,这个问题是⽤⼾⽆法容忍的。
为了解决这个问题,可以使⽤ Redis 将⽤⼾的 Session 信息进⾏集中管理,如图 2-13 所⽰,在这种模式下,只要保证 Redis 是⾼可⽤和可扩展性的,⽆论⽤⼾被均衡到哪台 Web 服务器上,都集中从 Redis 中查询、更新 Session 信息。
很多应⽤出于安全考虑,会在每次进⾏登录时,让⽤⼾输⼊⼿机号并且配合给⼿机发送验证码,
然后让⽤⼾再次输⼊收到的验证码并进⾏验证,从⽽确定是否是⽤⼾本⼈。为了短信接⼝不会频繁访问,会限制⽤⼾每分钟获取验证码的频率,例如⼀分钟不能超过 5 次,如图所⽰。
string SendCaptcha(phoneNumber) {
 key = "shortMsg:limit:" + phoneNumber;
 // 设置过期时间为 1 分钟 (60 秒),使⽤ NX,只在不存在 key 时才能设置成功
 bool r = Redis 执⾏命令:set key 1 ex 60 nx
 if (r == false) {
 // 说明之前设置过该⼿机的验证码了
 long c = Redis 执⾏命令:incr key
 if (c > 5) {
 // 说明超过了⼀分钟 5 次的限制了
 return nullptr;
 }
 }
 
 // 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次
 string validationCode = ⽣成随机的 6 位数的验证码();
 
 validationKey = "validation:" + phoneNumber;
 // 验证码 5 分钟(300 秒)内有效
 Redis 执⾏命令:set validationKey validationCode ex 300;
 
 // 返回验证码,随后通过⼿机短信发送给⽤⼾
 return validationCode ;
}
// 验证⽤⼾输⼊的验证码是否正确
bool CheckCaptcha(phoneNumber, validationCode) {
 validationKey = "validation:" + phoneNumber;
 
 string value = Redis 执⾏命令:get validationKey;
 if (value == null) {
 // 说明没有这个⼿机的验证码记录,验证失败
 return false;
 }
 
 if (value == validationCode) {
 return true;
 } else {
 return false;
 }
}

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

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

相关文章

查询语句来提取 detail 字段中包含 xxx 的 URL 里的 commodity/ 后面的数字串

您可以使用以下 SQL 查询语句来提取 detail 字段中包含 oss.kxlist.com 的 URL 里的 commodity/ 后面的数字串&#xff1a; <p><img style"max-width:100%;" src"https://oss.kxlist.com//8a989a0c55e4a7900155e7fd7971000b/commodity/20170925/20170…

业务开发 | 基础知识 | Maven 快速入门

Maven 快速入门 1.Maven 全面概述 Apache Maven 是一种软件项目管理和理解工具。基于项目对象模型的概念&#xff08;POM&#xff09;&#xff0c;Maven 可以从中央信息中管理项目的构建&#xff0c;报告和文档。 2.Maven 基本功能 因此实际上 Maven 的基本功能就是作为 Ja…

机器学习 - 词袋模型(Bag of Words)实现文本情感分类的详细示例

为了简单直观的理解模型训练&#xff0c;我这里搜集了两个简单的实现文本情感分类的例子&#xff0c;第一个例子基于朴素贝叶斯分类器&#xff0c;第二个例子基于逻辑回归&#xff0c;通过这两个例子&#xff0c;掌握词袋模型&#xff08;Bag of Words&#xff09;实现文本情感…

【Android开发】Android Studio汉化

前言 该插件是官方支持插件&#xff0c;未对任何软件进行修改和破解 Android Studio 是基于 IntelliJ IDEA 社区版开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于Android应用程序的开发。以下是为什么 Android Studio 能使用 IntelliJ IDEA 插件的原因&am…

后端java工程师经验之谈,工作7年,mysql使用心得

mysql 工作7年&#xff0c;mysql使用心得 mysql1.创建变量2.创建存储过程2.1&#xff1a;WHILE循环2.2&#xff1a;repeat循环2.3&#xff1a;loop循环2.4&#xff1a;存储过程&#xff0c;游标2.5&#xff1a;存储过程&#xff0c;有输入参数和输出参数 3.三种注释写法4.case …

ArcGIS Pro批量创建离线服务sd包

背景&#xff1a; 主要针对一个工程内有多个地图框项&#xff1a; 处理方法&#xff1a;通过Python脚本处理打包。 运行环境 在Pro的Python环境中去运行编写的Python脚本。 Python 脚本参考 import arcpy import os# Set output file names outdir r"d:\data\out&…

基于DeepSeek API和VSCode的自动化网页生成流程

1.创建API key 访问官网DeepSeek &#xff0c;点击API开放平台。 在开放平台界面左侧点击API keys&#xff0c;进入API keys管理界面&#xff0c;点击创建API key按钮创建API key&#xff0c;名称自定义。 2.下载并安装配置编辑器VSCode 官网Visual Studio Code - Code Editing…

信创领域的PostgreSQL管理员认证

信创产业&#xff0c;全称为信息技术应用创新产业&#xff0c;是中国为应对国际技术竞争、保障信息安全、实现科技自立而重点发展的战略性新兴产业。其核心目标是通过自主研发和生态构建&#xff0c;逐步替代国外信息技术产品&#xff0c;形成自主可控的国产化信息技术体系。 发…

使用 Visual Studio Code (VS Code) 开发 Python 图形界面程序

安装Python、VS Code Documentation for Visual Studio Code Python Releases for Windows | Python.org 更新pip >python.exe -m pip install --upgrade pip Requirement already satisfied: pip in c:\users\xxx\appdata\local\programs\python\python312\lib\site-pa…

IEEE期刊Word导出PDF注意事项

在系统上提交论文时候一般要求PDF文档&#xff0c;但是word直接转PDF可能存在一些问题&#xff1a; 部分图片不清晰。字体未嵌入PDF。间距发生了变化。字体发生了变化。一张图片显示不完全。 下面介绍word转PDF最稳妥的技巧以及如何实现全部字体的嵌入。 1. 操作流程 ① 另…

如何在 Elasticsearch 中设置向量搜索 - 第二部分

作者&#xff1a;来自 Elastic Valentin Crettaz 了解如何在 Elasticsearch 中设置向量搜索并执行 k-NN 搜索。 本文是三篇系列文章中的第二篇&#xff0c;深入探讨了向量搜索&#xff08;也称为语义搜索&#xff09;的复杂性以及它在 Elasticsearch 中的实现方式。 第一部分重…

DeepSeek的出现会对百度有多大影响?

当DeepSeek与ChatGPT等大模型接管搜索入口&#xff0c;我们正见证百年一遇的信息革命。 01 传统搜索已死&#xff1f;AI助手正在重写游戏规则&#xff01; 当DeepSeek与ChatGPT等大模型接管搜索入口&#xff0c;我们正见证百年一遇的信息革命。 就像汽车淘汰马车、触屏终结按键…

PyQt学习记录01——加法计算器

目录 PyQt学习记录01——加法计算器 PyQt学习记录02——串口助手 0. 安装配置 0.1 安装相关库 首先打开你的PyCharm程序&#xff0c;然后新建一个目录用于学习&#xff0c;其次在terminal中输入 pip install pyqt5如果你不具有科学上网能力&#xff0c;请改为国内源 pip …

jenkins备份还原配置文件

下载ThinBackup插件 方式1 从插件市场直接下载 Manage Jenkins->Manage Plugins->可选插件搜索 注意&#xff1a;有时可能因为网络或者版本问题下载不了&#xff0c;好像是默认下载最新版本&#xff0c;可选择手动安装&#xff01; 方式二 手动安装插件 点击查看手…

02.11 数据库

1.思维导图 2.题目 将 epoll 服务器、客户端拿来用客户端&#xff1a;写一个界面&#xff0c;里面有注册登录服务器&#xff1a;处理注册和登录逻辑&#xff0c;注册的话将注册的账号密码写入数据库&#xff0c;登录的话查询数据库中是否存在账号&#xff0c;并验证密码是否正…

Spring Boot整合DeepSeek实现AI对话(API调用和本地部署)

本篇文章会分基于DeepSeek开放平台上的API&#xff0c;以及本地私有化部署DeepSeek R1模型两种方式来整合使用。 本地化私有部署可以参考这篇博文 全面认识了解DeepSeek利用ollama在本地部署、使用和体验deepseek-r1大模型 Spring版本选择 根据Spring官网的描述 Spring AI是一…

苹果转型独立AR眼镜:一场技术与创新的深度探索

在科技日新月异的今天,增强现实(AR)技术正逐渐从科幻电影走进我们的日常生活。作为科技界的领头羊,苹果公司的每一步动向都备受关注。近期,苹果宣布暂停原定的Mac连接式AR眼镜计划,转而全力研发一款独立的AR眼镜。这一战略调整不仅反映了苹果对AR市场的深度洞察,也预示着…

Java小白入门基础知识(一)

1.初识Java java源程序通过javac 编译生成字节码文件&#xff0c;通过java命令运行java程序 总结&#xff1a; 1&#xff09;在一个Java文件中&#xff0c;只能有一个public class 2&#xff09;public class一定要和文件名一致 3&#xff09;类里面包含方法 4&#xff09…

通过 Docker 安装和部署 KeyDB v6.3.4 的详细步骤

KeyDB 是一种高性能的开源内存数据库&#xff0c;最初是基于 Redis 项目开发的&#xff0c;但在性能、特性和功能上进行了许多增强和改进。它兼容 Redis 的大部分命令和数据结构&#xff0c;因此可以作为 Redis 的替代品使用&#xff0c;尤其是在需要更高性能和多线程支持的场景…

【JavaEE进阶】依赖注入 DI详解

目录 &#x1f334;什么是依赖注入 &#x1f384;依赖注入的三种方法 &#x1f6a9;属性注⼊(Field Injection) &#x1f6a9;Setter注入 &#x1f6a9;构造方法注入 &#x1f6a9;三种注⼊的优缺点 &#x1f333;Autowired存在的问题 &#x1f332;解决Autowired存在的…