当前位置: 首页 > news >正文

Redis String全方位指南:命令、编码、时间复杂度与应用场景

前言

Redis 作为一个高性能的键值数据库,其核心在于提供了丰富的数据类型来满足各种业务场景的需求。在所有数据类型中,String(字符串)是最基础也是最核心的一种。无论是简单的键值缓存,还是复杂的计数器、分布式锁,都离不开 String 类型的支持。本文将深入探讨 Redis 中 String 类型的底层原理、常用命令以及多样化的应用场景,帮助你彻底掌握这一关键数据结构,为高效使用 Redis 打下坚实的基础。

redis所有的key都是字符串
value的类型都是存在差异的

redis中的字符串,直接就是按照二进制的方式存储的
(不会做任何的编码转换,存的是啥,取出来的就是啥)

JSON、xml、二进制数据(音频、视频、图片)

音视频的大小体积可能比较大
redis对于string类型限制了最大的大小是512MB

redis单线程模型,希望进行的操作都能比较快速

Mysql默认的字符集是拉丁文,插入中文就会失败的

但是redis不会出现这种情况的,存啥形式取出来的就是啥

一般来说redis遇到乱码问题的概率较小

set 和get

set格式

SET key value [expiration EX seconds|PX milliseconds] [NX|XX]

通过一个命令创建键值对并且设置超时时间

set key value ex 10转换为
set key value   创建键值对
expire key 10  设置过期时间为10

除了上面使用ex设置超时时间为秒
还可以使用px设置超时时间为毫秒

set key value px 10

后面的

NX和XXNX表示的是如果Key不存在的话,才设置
如果key存在的话,则不设置(返回nil)XX则相反
如果key存在才设置(相当于更新key的value,可能会更改原来的数据类型,原来的key的ttl(生存时间)也会失效的)
如果key不存在的话,则不设置(返回nil)这里的两个选项是互斥的,所以二者只能存在一个

redis文档说明
[]相当于一个独立的单元,表示选项(可有可无)
其中的 | 表示或者的意思,多个只能出现一个
一次性将命令完成,这样可以减少网络开销

删库命令,将redis上所有的键值对都删除

FLUSHALL

image.png

image.png

在后面加上NX,如果不存在的话才进行设置,如果存在的话就返回nil
这里我们的key2已经消失了,因为我们上面设置了过期时间了
image.png
这里在后面加上XX,如果key存在的话就进行value的更新
image.png

对于GET来说,只是支持字符串类型的value
如果value是其他的类型的话,使用GET获取就会出错了image.png
我们这里的key类型是list,所以我们这里使用GET是不能获取value的
image.png

mset 和mget

一次可以操作多组键值对的

执行N次get命令会进行多次网络传输的
image.png
执行一次get命令的话只进行一次get传输的image.png

MSET key value [key value ...]

一次性创建多个键值对
image.png
虽然可以设置多个键值对,但是不要太多了,如果这个命令执行时间太长了的话,会造成阻塞其他的命令

使用mget可以一次查询多个key的value的值
image.png
时间复杂度是O(N)
这个N是key的数量

SETNX 、SETEX、PSETEX

SETNX  不存在才能设置,存在则设置失败

被框出来的这个命令没有生效,因为key1的值是没有改变的

setex的使用方法

setex key time value

image.png

setex和psetex都是设置key的过期时间,前者的单位是秒,后者的单位是毫秒

上面都是针对set的一些常见用法,进行了缩写

这样使用者的门槛就越低了

incr和incrby

incr  针对value+1
#此时key对应的value必须是整数,进行这个命令后的返回值是+1后的值incrby  针对value+n
#此时key对应的value必须是整数,进行这个命令后的返回值是+n后的值

image.png
如果value不是整数的话,这里进行incr的话会出现报错的
image.png
小数也是不行的,也是会出现报错的
image.png
并且如果值过大的话也是会报错的
image.png
我们这里原本是没有key3的,然后使用incr key3
incr操作的Key如果是不存在的话,就会将这个key的value当做0
image.png

针对某个key的value加上n,返回加上后的值
image.png
incrby加上正数和负数都是可以的

decr 、decrby 和incrbyfloat

decr  针对value-1decrby  针对value-nincrbyfloat  针对value +/- 小数

key对应的value必须是整数,在64位的范围内,如果这个Key对应的value不存在,都是当做0的

image.png
这个操作方法和incr一样的

incrbyfloat针对浮点数image.png
image.png

append

如果Key已经存在并且是一个string,命令会将value追加到原有string的后边,如果Key不存在,则效果等同于SET命令创建一个新的键值对

append key value

返回值是追加完字符串的长度

image.png
在已经存在的Key后面追加一个字符串
如果不存在对应的key的话就会新建一个键值对
image.png

image.png
这里返回的是6个字节
append返回值,长度的单位是字节

redis的字符串,不户籍对字符编码做任何处理(redis不认识字符,只认识字节)

当前xshell终端,默认的字符编码是utf8
在终端输入汉字之后,也是按照utf8编码的

一个汉字在utf8字符集中,通常是3个字节的

这里我们使用get查看key3的内容
image.png

  • 返回 "\xe4\xbd\xa0\xe5\xa5\xbd" → 这是 你好 的 UTF-8 字节序列的转义表示
    那么我们如何在使用get查看的时候,显示的是中文呢?

那么我们得在启动redis客户端的时候,加上一个 --raw这样的选项

就可以使redis客户端能够自动的把二进制数据尝试翻译了image.png

getrange

在C++中的std::string substr
返回key对应的子串,由start和end确定(左闭右闭)

getrange key start end

redis中指定的区间是闭区间

redis的下标是可以支持负数的
-1倒数第一个元素
下标为len-1的元素
image.png

但是如果是汉字的话,那么此时进行子串切分,我们查询到的可能就不准了
image.png
image.png

setrange

将范围中的子串进行修改

setrange key offset value

offset表示的是偏移量,从第几个字节开始进行替换的
value表示的是替换的字符

结束就看value的长度了
从第4个字符开始进行更新字符串,更新为qq
image.png
返回值是替换之后新的字符串的长度image.png
\x表示当前是一个16进制的数字
凭空生成一个字节,这个字节里面的内容就是0x00
aaa就被追加到了0x00的后面了

setrange针对不存在的key也是可以操作的,不过会把offset之前的内容填充乘0x00的

strlen

获取字符串的长度的,单位是字节

strlen key

如果key中存放的类型不是key的话就会报错的
image.png

image.png
返回的是key的长度,如果key不存在的话,返回0

命令总结

好的,这是根据图片内容生成的表格:

命令执行效果时间复杂度
set key value [key value…]设置 key 的值是 valueO(k), k 是键个数
get key获取 key 的值O(1)
del key [key …]删除指定的 keyO(k), k 是键个数
mset key value [key value …]批量设置指定的 key 和 valueO(k), k 是键个数
mget key [key …]批量获取 key 的值O(k), k 是键个数
incr key指定的 key 的值 +1O(1)
decr key指定的 key 的值 -1O(1)
incrby key n指定的 key 的值 +nO(1)
decrby key n指定的 key 的值 -nO(1)
incrbyfloat key n指定的 key 的值 +nO(1)
append key value指定的 key 的值追加 valueO(1)
strlen key获取指定 key 的值的长度O(1)
setrange key offset value覆盖指定 key 的从 offset 开始的部分值O(n), n 是字符串长度, 通常视为 O(1)
getrange key start end获取指定 key 的从 start 到 end 的部分值O(n), n 是字符串长度, 通常视为 O(1)

string内部编码方式

字符串类型的内部编码有3种

  • int:8个字节的长整形
  • embstr:小于等于39个字节的字符串(压缩字符串)
  • raw:大于39个字节的字符串(普通字符串)
    redis会根据当前值的类型和长度动态决定使用哪种内部编码实现

我们可以使用命令查看对应key的编码方式

object encoding key

开源的组件,往往考虑的是通用型,大厂的话可能会遇到一些极端的业务场景,往往就需要根据当前的极端业务,针对上述的开源组件进行定制化

使用redis存储小数的时候,显示的编码格式是embstr,本质上还是当做字符串来存储的

string类型应用场景

作为缓存

整体的思路:应用服务器访问数据的时候,先查询redis,如果redis存在该数据,就直接取数据交给应用服务器,不继续访问数据库了
image.png
如果redis上数据不存在的话,再去去读mysql,把读到的结构,返回给应用服务器,同时,把这个数据也写到redis中

redis这样的缓存,经常来存储热点数据
高频被使用的数据,这个定义方式结合业务场景有很多种方式
这就相当于将最近使用到的数据作为热点数据

上述策略存在一个明显的问题,随着时间的推移,肯定会有越来越多的Key在redis上访问不到,从而从mysql中去读并写入redis了,此时redis中的数据不是越来越多了么

解决方案
1、在把数据写给redis的同时,给这个key设置一个过期时间
2、redis也在内存不足的时候,提供了淘汰策略

计数功能

image.png
通过redis统计到数据,然后给其他统计数据仓库进行数据的统计

共享对话

image.png

image.png
image.png

手机验证码

在当今的互联网应用中,手机验证码是验证用户身份、确保账户安全的重要环节。利用 Redis 的 String 类型,我们可以轻松、高效地实现这一功能。

其核心思路是:

  1. 当用户请求发送验证码时,后端服务器会生成一个随机的数字(例如6位数)。

  2. 将用户的手机号作为 key,生成的随机验证码作为 value,存入 Redis 中。

  3. 同时,为这个 key 设置一个较短的过期时间,例如 5 分钟。这可以通过 SETEX 命令或者 SET 命令配合 EX 选项一步完成,确保了操作的原子性。

示例命令:

codeBash

# 设置手机号为 188xxxxxxxx 的验证码为 123456,并设置5分钟(300秒)后过期
SETEX 188xxxxxxxx 300 123456

当用户输入验证码进行校验时,服务器只需从 Redis 中根据手机号这个 key 来获取 value,并与用户提交的验证码进行比对。

  • 如果能获取到值,并且与用户输入的一致,则验证通过。

  • 如果获取不到值(返回 nil),则说明验证码已经过期或不存在,验证失败。

使用 Redis 存储手机验证码的优势:

  • 高性能:Redis 基于内存操作,读写速度极快,可以轻松应对高并发的验证码请求。

  • 自带过期策略:使用 SETEX 或 EX 选项可以非常方便地管理验证码的生命周期,无需手动删除,有效节约了存储空间并简化了业务逻辑。

  • 简化数据库压力:将验证码这类临时性、高频读写的数据从关系型数据库(如 MySQL)中剥离出来,可以显著降低主数据库的负载。

总结

本文详细介绍了 Redis 中最基础、最核心的 String 数据类型。我们了解到,Redis 的 key 均为字符串,而 String 类型的 value 以二进制安全的方式存储,不会进行任何编码转换,这使其能够存储包括 JSON、图片、音视频在内的任意二进制数据,最大支持 512MB。

核心命令回顾:

  • 基础操作:SET 和 GET 是最基本的读写命令,而 MSET 和 MGET 提供了批量操作的能力,能有效减少网络开销。

  • 原子操作与选项:SET 命令的 NX(不存在才设置)和 XX(存在才设置)选项,以及 SETNX、SETEX 等命令,为实现分布式锁、缓存管理等功能提供了原子性保障。

  • 计数器功能:INCR、DECR、INCRBY 等一系列命令使 String 类型可以作为高性能的原子计数器使用,且能处理整数和浮点数。

  • 字符串处理:APPEND、GETRANGE、SETRANGE 和 STRLEN 等命令提供了对字符串值进行追加、截取、覆盖和长度计算等细粒度操作的能力。

内部编码:
Redis 会根据存储内容和长度,动态选择 int、embstr 或 raw 三种内部编码方式,以优化内存使用和执行效率。

典型应用场景:
最后,我们探讨了 String 类型的四大典型应用场景:

  1. 数据缓存:作为热点数据的缓存层,降低后端数据库压力。

  2. 计数功能:适用于文章阅读量、用户点赞数等统计场景。

  3. 共享会话(Session):在分布式系统中存储和共享用户登录信息。

  4. 手机验证码:利用其高性能和过期策略,安全、高效地处理临时验证信息。

总而言之,深入理解并熟练运用 String 类型是精通 Redis 的基石,其灵活性和高性能使其在各种技术方案中都扮演着不可或缺的角色。

http://www.lryc.cn/news/626318.html

相关文章:

  • RK-Android11-PackageInstaller安装器自动安装功能实现
  • KubeBlocks AI:AI时代的云原生数据库运维探索
  • 3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
  • Origin将普通点线图升级为3D点线图
  • ETL 工具选型评测:2025 年 Top 5 工具优缺点对比(附评分表)
  • 【自记】Power BI 中FILTER、CALCULATE 和 CALCULATETABLE 三个函数详细说明
  • React框架超详细入门到实战项目演练【前端】【React】
  • React15.x版本 子组件调用父组件的方法,从props中拿的,这个方法里面有个setState,结果调用报错
  • 【Coze】Windows 环境下使用 Docker 部署 Coze Studio 的详细指南
  • 基于分布式环境的令牌桶与漏桶限流算法对比与实践指南
  • Day 40:训练和测试的规范写法
  • 008.Redis Cluster集群架构实践
  • RabbitMQ:SpringAMQP Topic Exchange(主题交换机)
  • Linux中Cobbler服务部署与配置(快速部署和管理 Linux 系统)
  • mac电脑软件左上角的关闭/最小化/最大化按钮菜单的宽度和高度是多少像素
  • Mac 4步 安装 Jenv 管理多版本JDK
  • Mac 上安装并使用 frpc(FRP 内网穿透客户端)指南
  • 第四章:大模型(LLM)】07.Prompt工程-(4)思维链(CoT, Chain-of-Thought)Prompt
  • 第四章:大模型(LLM)】07.Prompt工程-(5)self-consistency prompt
  • 编译安装 Nginx
  • 从AI小智固件到人类智能:计算技术的层级跃迁
  • Linux-----《Linux系统管理速通:界面切换、远程连接、目录权限与用户管理一网打尽》
  • JavaScript 检查给定的四个点是否形成正方形(Check if given four points form a square)
  • [特殊字符] 小豆包 API 聚合平台:让 AI 接入更简单、更高效
  • PyTorch API 7
  • Linux 文件系统权限管理(补充)
  • pinctrl和gpio子系统实验
  • 前后端联合实现文件上传,实现 SQL Server image 类型文件上传
  • LeetCode热题100--101. 对称二叉树--简单
  • 【Kafka】常见简单八股总结