Redis 第六讲 --- 数据类型篇 string指令

发布于:2025-07-08 ⋅ 阅读:(12) ⋅ 点赞:(0)

前言:

在《Redis 第五讲 --- 数据类型篇 数据类型与内部编码》中,我们深入探讨了Redis核心数据类型的分类及其底层编码机制,理解了不同场景下数据结构的选择逻辑。今天,我们进入《Redis 第六讲 --- 数据类型篇 string指令》,聚焦最基础且强大的string类型

string类型不仅是Redis的基石,还因其灵活性支持丰富操作:从简单的键值存储(set/get)到复杂功能(原子计数incr、过期管理ex、条件设置nx)。本讲将系统解析string指令的核心细节:

  • 存储优势:二进制安全设计,大幅降低乱码风险;

  • 高效操作mset/mget批量处理(O(N))、append拼接、getrange子串截取;

  • 数值运算incrby对整数原子增减(O(1)),注意浮点数与大数的限制;

  • 汉字处理:以字节存储的注意事项,避免错误切分;

  • 实战技巧flushall风险预警、set key value ex过期控制、setnx分布式锁实现等。

通过本讲,外面将掌握主要string指令的妙用,为高性能开发铺平道路。


目录

前言:

一、string的类型介绍

二、set与get

2.1 set

选项:

返回值:

演示:

2.2 get

2.3 flushall

三、incr与decr系列

四、append与getrange

4.1 APPEND

4.2 GETRANGE

五、setrange与strlen

5.1 setrange

5.2 strlen

总结:


一、string的类型介绍

字符串类型是 Redis 最基础的数据类型,关于字符串需要特别注意:

1)⾸先 Redis 中所有的键的 类型都是字符串类型,⽽且其他⼏种数据结构也都是在字符串类似基础上构建的,例如列表和集合的 元素类型是字符串类型,所以字符串类型能为其他 4 种数据结构的学习奠定基础。

2)其次,字符串类型的值实际可以是字符串,包含⼀般格式的字符串或者类似 JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚⾄是⼆进制流数据,例如图⽚、⾳频、视频等。不过⼀个字符 串的最⼤值不能超过 512 MB。

注意:由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的,所以 Redis 是不处理字符集 编码问题的,客⼾端传⼊的命令中使⽤的是什么字符集编码,就存储什么字符集编码。

所以Redis的使用不像MySQL那样容易出现乱码问题。

在MySQL当中,我们的存储与查询的字符集不同的时候,会出现乱码问题,最典型就是关于汉字的存储,但是在Redis这里不一样,Redis统一存储成二进制,查询的结果以十六进制显示。如下

我们借助网上的一些转进制工具查看一下结果,

注意:“\x”是表示后面的符号是十六进制的意思。

如果我们想要让Redis直接进行内部编码转化,直接指令后带选项 --raw。【注意:这里的指令是要求在启动redis客户端的时候带上的。】

 现在我们已经对string类型有了初步的介绍,我们下面看一下string类型的指令吧。


二、set与get

这两个指令其实在string这里有我们前面学习到的全局指令没啥不同,我们直接来看一下使用。

2.1 set

将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖,⽆论原来的数据类型是什么。之 前关于此 key 的 TTL 也全部失效。

时间复杂度:O(1)

选项:

SET 命令⽀持多种选项来影响它的⾏为:

• EX seconds⸺使⽤秒作为单位设置 key 的过期时间。

• PX milliseconds⸺使⽤毫秒作为单位设置 key 的过期时间。

• NX ⸺只在 key 不存在时才进⾏设置,即如果 key 之前已经存在,设置不执⾏。

• XX ⸺只在 key 存在时才进⾏设置,即如果 key 之前不存在,设置不执⾏。

针对set的一些常见用法,进行了缩写;之所以这样搞,就是为了让操作更符合人的直觉.(使用者的门槛就越低,要背的东西就越少)

那这些选项什么意思呢?

就是说这个set指令可以一次执行多条指令的效果,像之前的expire指令,功能就被做成一个选项了,降低了客户端与服务端的网络通信次数,减少消耗。

例如:set key value ex 10  相当于  set key value  +  expire key 10。

注意:由于带选项的 SET 命令可以被 SETNX 、 SETEX 、 PSETEX 等命令代替,所以之后的版本 中,Redis 可能进⾏合并。

返回值:

• 如果设置成功,返回 OK。

• 如果由于 SET 指定了 NX 或者 XX 但条件不满⾜,SET 不会执⾏,并返回 (nil)。

还有一点,就是关于Redis文档查询的问题。

当我们看到一条指令发现这样的格式:

格式说明:[]相当于一个独立的单元,表示可选项(可有可无的),其中|表示”或者”的意思,多个只能出现一个。[]和[]之间,是可以同时存在的.

话不多说,我们直接演示一下吧!

演示:

1)set的覆盖效果

2)set的选项演示

我们成功的将两条指令结合成一条指令。 

当key已经存在的时候,NX就无法继续设置了。

2.2 get

获取 key 对应的 value。如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错。 语法:

1 GET key

时间复杂度:O(1)

返回值:key 对应的 value,或者 nil 当 key 不存在。 

演示:

但是可以会有小伙伴问,Redis 的mset指令可以一次设置多个key,那么get可以获得多个value吗?

答案是不可以的!下面我们来演示一下。

 

但是我们Redis还有对应的同时对多个key进行操作的指令,只需要在前面加上m就好了。

使⽤ mget / mset 由于可以有效地减少了⽹络时间,所以性能相较更⾼。如果以后存在大量的key设置与获取我们可以考虑使用mset与mget。

2.3 flushall

在告诉大家一个闯祸小技巧 --- 指令 flushall

FLUSHALL可以把redis上所有的键值对都带走,以后在公司,尤其是生产环境的数据库,千万千万不敢敲!!

例如我们上面演示指令产生了许多的没有的指令,现在我们是学习阶段可以人为的删除一下。

演示:

注意:对于GET来说,只是支持,字符串类型的value,如果value是其他类型,使用GET获取就会出错!!关于如何获取其他类型的指令那就是我们后面学习的内容了。


三、incr与decr系列

这个系列的函数其实针对value为数字的字符串进行操作的。它们可以对value进行加减等操作。

  1. incr:针对 value + 1
  2. incrby:针对 value + n
  3. decr:针对 value -1
  4. decrby:针对 value - n
  5. incrbyfloat:针对 value +/- 小数

但是使用也是存在限制的,比如我们操作的value值太大了,超过了8个字节能表示的最大数值,或者是这个key根本不存在但是这种情况比较特殊,上述指令会把这个key的value当成0开始操作。

特殊的存在::incrbyfloat
把 key 对应的 value 进行+ - 运算.,运算的操作数可以是浮点数。
虽然此处没有提供减法版本的命令,但是使用redis进行的计数操作,一般都是针对整数来进行的, 能用加上负数的形式来实现减法。

为啥说这个指令特殊呢?

因为这个指令不想上面的其他四个指令,它们都有对应的相反操作的指令。

废话不说,直接开始演示。

演示:

1)incr 与incrby

这几个指令在使用完成后,都是会打印出操作结果的。

2)decr 与 decrby

在进行减法操作的时候,直接减去负数也是可以达到加法的效果的。

3)incrbyfloat

上面的几个指令是无法对浮点数进行操作的,只有incrbyfloat可以操作。

注:上述操作的时间复杂度,都是0(1),由于redis处理命令的时候,是单线程模型.多个客户端同时针对同一个key进行incr操作,不会引起"线程安全”问题。


四、append与getrange

毕竟我们的string类型主要是针对字符串进行操作的,所以我们怎么能少了对字符串操作的指令呢?

字符串也有一些指令支持一些常用的操作.拼接,获取/修改字符串的部分内容,获取字符串长度,

我们下面来介绍一下。

4.1 APPEND

如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key 不存在, 则效果等同于 SET 命令。
语法:

1 APPEND KEY VALUE

时间复杂度:O(1). 追加的字符串⼀般⻓度较短, 可以视为 O(1)

.返回值:追加完成之后 string 的⻓度,长度的单位是字节!!
注意:redis的字符串,不会对字符编码做任何处理.(redis不认识字符,只认识字节)

演示:

我们当前的xshell终端,默认的字符编码是utf8.,在终端中输入汉字之后,也就是按照utf8编码的
而一个汉字在utf8字符集中,通常是3个字节的;在gbk编码当中则是占据2个字节。

4.2 GETRANGE

返回 key 对应的 string 的⼦串,由 start 和 end 确定(左闭右闭)。

编程这个大圈子中,区间大多是前闭后开,但是确实有特殊情况,比如Redis但是这个跟别的设计脱节还是不好的。但是不同之处还没完,正常下标都是从0开始的整数,redis的下标是可以支持负数的,还好开头还是从0开始的。

语法:

1 GETRANGE key start end

可以使⽤负数表⽰倒数。

-1 代表 倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据 string 的⻓度调整 成正确的值。

时间复杂度:O(N). N 为 [start, end] 区间的⻓度. 由于 string 通常⽐较短, 可以视为是 O(1)

返回值:string 类型的⼦串

演示:

1)英文

2)中文

这里我启动redis客户端的时候带上了 --raw选项,所以现在还是截取比较好的。

但是如果不是raw模式呢?

这样的截取使用的是字节为单位,所以会截出一些没有意义的乱码。

所以字符串中保存的是汉字,此时进行子串切分,很可能切出来的就不是完整的汉字了
上述的代码,是强行切出了中间的四个字节,随便这么一切,切出的结果在utf8码表上不知道能查出啥了。


五、setrange与strlen

5.1 setrange

覆盖字符串的⼀部分,从指定的偏移开始。
语法:

1 SETRANGE key offset value

时间复杂度:O(N), N 为 value 的⻓度. 由于⼀般给的 value ⽐较短, 通常视为 O(1).

返回值:替换后的 string 的⻓度。 

演示:

1)英文

2)中文

这个key对应的value是“张三与李四”

如果当前咱们value是一个中文字符串.进行setrange的时候,是可能会搞出问题的!!

3)对于不存在的key操作呢?

我们发现一样是可以操作的,不过字符串前面新增了几个0.

结论;setrange针对不存在的key也是可以操作的.不过会把offset之前的内容填充成0x00。

5.2 strlen

strlen获取到字符串的长度.(单位是字节),其他的没啥好说的,基本上与C语言的函数没啥区别。

获取 key 对应的 string 的⻓度。当 key 存放的类似不是 string 时,报错。

语法:

1 STRLEN key

时间复杂度:O(1)

返回值:string 的⻓度。或者当 key 不存在时,返回 0。 

注:单位是字节。

演示:


总结:

至此,我们完成了string指令的全面解析:从基础存取、过期管理到原子运算与字符串操作,您已掌握如何高效利用Redis处理文本、数值及二进制数据。特别注意汉字存储以字节为单位的特性,避免子串截取时的乱码问题;同时善用setnxincrby等原子操作,可大幅简化分布式逻辑。

在下一讲《Redis 第七讲 --- 数据类型篇 string的内部编码》中,我们将深入string的底层实现:揭秘int、embstr、raw三种编码的动态转换机制,分析内存优化策略与性能取舍。理解内部编码,才能真正发挥Redis极致性能。

我们下期见!


网站公告

今日签到

点亮在社区的每一天
去签到