Redis - String 字符串

前言

下表中包含本博客提到的所有命令

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

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

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

3)Redis 中的 String 类型,直接是按照二进制数据的格式存储的,没有涉及到任何的编码转换,存的是什么取出来的还是什么,所以 Redis 出现乱码的概率很小

常见命令

SET 设置键值对

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

语法:

java 复制代码
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 之前不存在,设置不执⾏。可以理解为更新,只有存在才能更新,原来不存在就更新不了

结果:

如果设置成功,返回 OK。

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

GET 获取 value 值

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

语法:

java 复制代码
GET key

时间复杂度:O(1)

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

MSET ⼀次性设置多个 key 的值

⼀次性设置多个 key 的值。

语法:

java 复制代码
MSET key value [key value ...]

时间复杂度:O(N) N 是 key 数量

返回值:永远是 OK

MGET ⼀次性获取多个 key 的值

⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil

语法:

java 复制代码
MGET key [key ...]

时间复杂度:O(N) N 是 key 数量

多次 get vs 单次 mget

Redis 是客户端-服务器 结构的程序,所以在命令行输入的每条命令都会被 Redis 构造成 HTTP 请求发送给服务器,服务器接收到请求根据请求的内容,将要返回的数据构造成 HTTP 响应返回

所以当我们要获取多个数据时,采用 get 命令多次获取,就会构造多个 HTTP 请求,接收多个 HTTP 响应,而采用 mget 命令一次获取所有的数据,就只会构造一个 HTTP 请求,返回一个 HTTP 响应

很显然,使用 mget 命令批量获取数据的方式可以节省很多的网络资源

· 但也不能批量的获取太多的数据,要有节制,如果一次性批量获取太多的数据,就会导致该命令的执行时间过长,而 Redis 是单线程的程序,当前命令执行时间过长就会导致后面的命令没有时间执行,就会导致客户端迟迟得不到响应,造成客户端阻塞

SETNX,SETEX,PSETEX

SETNX 等同于 SET KEY VALUE NX 只在 key 不存在时才进⾏设置,即如果 key 之前已经存在,设置不执⾏

SETEX 等同于 SET KEY VALUE EX 在设置键值对的同时设置秒级过期时间

PSETEX 等同于 SET KEY VALUE PX 在设置键值对的同时设置毫秒级过期时间

时间复杂度:O(1)

返回值:1 表⽰设置成功。0 表⽰没有设置。

计数命令

INCR 将数字加 1

将 key 对应的 value 表⽰的数字加⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。

至于为什么 value 是 String 类型,但却能对保存的数字类型进行计算,是因为底层的编码存储数字用的是 int ,关于 Redis 各个类型底层编码的具体实现推荐看Redis 的数据结构和内部编码【雨林优选】【面试重点】

语法:

java 复制代码
INCR key

时间复杂度:O(1)

返回值:integer 类型的数据加完后的数值

INCRBY 将数字加指定的值

将 key 对应的 value 表⽰的数字加上对应的值。如果 key 不存在,则视为 key 对应的 value是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。

语法:

java 复制代码
INCRBY key decrement

时间复杂度:O(1)

返回值:integer 类型的数据加完后的数值。

当然如果加的值是负数,就能得到减法的效果

DECR 将数字减 1

将 key 对应的 value 表示的数字减⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。

语法:

java 复制代码
DECR key

时间复杂度:O(1)

返回值:integer 类型的数据减完后的数值。

DECRBY 将数字减指定的值

将 key 对应的 value 表⽰的数字减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。

语法:

java 复制代码
DECRBY key decrement

时间复杂度:O(1)

返回值:integer 类型的数据减完后的数值。

当然如果减的值是负数,就能得到加法的效果

INCRBYFLOAT 将浮点数加指定的值

将 key 对应的 value 表⽰的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的不是 string 类型,或者不是⼀个浮点数,则报错。允许采⽤科学计数法表⽰浮点数。

语法:

java 复制代码
INCRBYFLOAT key increment

时间复杂度:O(1)

返回值:加/减完后的数值。

其他命令

APPEND 追加字符串

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

语法:

java 复制代码
APPEND KEY VALUE

时间复杂度:O(1).

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

返回值:追加完成之后 value 的⻓度。

GETRANGE 获取子串

返回 key 对应的 value 的⼦串,由 start 和 end 确定(左闭右闭)。可以使⽤负数表⽰倒数。-1 代表倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据string 的⻓度调整成正确的值。

语法:

java 复制代码
GETRANGE key start end

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

返回值:string 类型的⼦串

注意当键值对中存的数据是中文时,如果获取子串不当就会出现一定的问题

解释:由于博主使用的 xshell 软件的编码方式是 utf8 ,所以一个中文字符由 3 个字节表示,而 GETRANGE 获取子串操作的单位是字节,所以上述的例子就截去了第一个和最后一个字节,因此导致第一个中文字符和最后一个中文字符无法正常表示

当我们截去前三个字节和后三个字节就成功去除了'你' 和 '界' 两个中文字符

提醒:一个中文字符由多少个字节组成不是固定的,要看具体的编码方式

SETRANGE 覆盖字符串

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

语法:

java 复制代码
SETRANGE key offset value

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

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

STRLEN 获取字符串长度

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

语法:

java 复制代码
STRLEN key

时间复杂度:O(1)

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

相关推荐
前行的小黑炭20 分钟前
设计模式:为什么使用模板设计模式(不相同的步骤进行抽取,使用不同的子类实现)减少重复代码,让代码更好维护。
android·java·kotlin
Java技术小馆25 分钟前
如何设计一个本地缓存
java·面试·架构
数据智能老司机1 小时前
CockroachDB权威指南——SQL调优
数据库·分布式·架构
数据智能老司机1 小时前
CockroachDB权威指南——应用设计与实现
数据库·分布式·架构
XuanXu1 小时前
Java AQS原理以及应用
java
数据智能老司机1 小时前
CockroachDB权威指南——CockroachDB 模式设计
数据库·分布式·架构
风象南4 小时前
SpringBoot中6种自定义starter开发方法
java·spring boot·后端
mghio13 小时前
Dubbo 中的集群容错
java·微服务·dubbo
咖啡教室18 小时前
java日常开发笔记和开发问题记录
java