Redis:string类型
- string命令
- 设置与读取
- SET
- GET
- MSET
- MGET
 
- 数字操作
- INCR
- INCRBY
- DECR
- DECRBY
- INCRBYFLOAT
 
- 字符串操作
- APPEND
- STRLEN
- GETRANGE
- SETRANGE
 
 
- 内部编码
- int
- embstr
- raw
 
 
在Redis中,字符串string存储的是二进制,以byte为单位,输入的二进制是什么,那么存储的就是什么,string不进行编码的转化。
因此string类型可以存储非常多种类的数据,比如ASCII编码字符串,UTF-8编码字符串,int整型,甚至可以存储图片,视频音频等,因为这些都是二进制,怎么存进去的,最后就怎么解析。
当然,一般不会用string存储图片,视频音频,因为它们太大了,内存没那么多空间,只是理论上可行。
string命令
设置与读取
SET
- 设置一个key
set key value [EX seconds | PX milliseconds] [NX | XX]
由于set默认情况下就是设置一个string,所以没有什么其它的特殊语法,此处介绍两个选项。
- EX seconds:以秒为单位,设置超时时间
- PX milliseconds:以毫秒为单位,设置超时时间
- NX:如果- key不存在才设置,如果存在返回- nil
- XX:如果- key存在就更新,如果不存在返回- nil
注意:通过XX更新后,原先的过期时间会失效,数据类型也有可能变化
示例:

该指令设置了一个字符串key1,内容为12345,过期时间为10 s,nx表示只有不存在才设置。
示例:

和刚才一样设置一个超时时间10 s的字符串,随后立刻通过xx选项进行更新操作。更新后发现,ttl的返回值变成了-1,这说明原先ex设置的过期时间被覆盖了。
GET
- 获取key对应的value
get key
和set一样,get的默认数据类型就是string,如果value类型不是string,会发生报错。
MSET
- 一次设置多个key
mset key value [key value ...]
由于Redis基于网络通信,所以多条指令压缩为一条指令就是把多个网络请求压缩为一个,对效率提升非常明显。所以Redis提供了这样的一次设置多组键值对的指令。
MGET
- 一次获取多个key的value
mget key [key ...]
示例:

数字操作
由于string内部还可以存储数字,所以Redis还提供了数字操作的命令。
INCR
- 指定整数+1
incr key
返回值是字符串+1后的结果。
示例:

如图,设置了一个数字后,通过incr对其自增,返回了124,并且get num1的值也自增了。

当设置的数字值过大,此时就不会被解析为数组,而是解析为字符串。此时incr执行失败,检测到num2类型为embstr。string可以存储的最大整型为64位有符号整型,相当于C/C++中的long long。

另外的,incr可以操作一个空值,并且将其视为数字0。此处通过get检测num3不存在,但是incr num3成功执行,结果为1。
INCRBY
- 指定整数,增加指定的值
incrby key increment
key对应的value的值就会增加increment,其余特性和incr相同。
示例:

注意:incrby可以增加一个负数,也就是做减法。但是不能操作浮点数,只能操作整型。
DECR
- 指定整数-1
decr key
返回值是字符串-1后的结果。
DECRBY
- 指定整数,减少指定的值
decrby key decrement
key对应的value的值就会减少decrement,其余特性和decr相同。
同样的,decrby也可以操作负数,此时相当于增加decrement的绝对值。
INCRBYFLOAT
- 指定浮点数/整数,增加指定的值
incrbyfloat key increment
同样的,返回key的value自增后的值。
示例:

与整型不同,Redis没有提供DECRBYFLOAT指令,也就是说浮点数想要进行减法,只能让increment为负数。
字符串操作
回到string的本职工作,自然是要存储字符串,字符串也要提供相关的操作。
APPEND
- 将value追加字符串的尾部
append key value
返回追加完成后,字符串的总长度。

如图完成了一个字符串的追加。

同样的,如果原先key不存在,则视为一个空串,直接追加。
STRLEN
- 获取字符串的长度
strlen key
返回字符串的长度,以字节为单位。
如果遇到中文:

此时根据UTF-8编码,一个中文占3 byte,所以两个中文的长度是6。如果再输出这个中文字符串,会得到一个乱码。此处\x是一个转义字符,表示一个十六进制数字。也就是说\xe4整体是一个十六进制的数字,占一个字节。
其实这个十六进制数字,就是汉字的编码,比如\xe4 \xdb \xa0就是汉字"你"。如果想要让Redis支持输出中文,在启动时要加入--raw选项:

这样就可以正常输出中文了,但是要注意,如果key不存在,原本是输出nil,但是会被转化为一个空行。
GETRANGE
- 返回字符串指定范围的字串
getrange key start end
获取的字串是下标范围[start, end]的闭区间,下标从0开始。而且支持使用负数,最后一个字符串的负数编码为-1。
示例:

第一次截取,区间为[0, 5],由于是闭区间,所以有6个字符。
 第二次截取,区间为[0, -1],-1就是最后一个字符,又是闭区间,所以输出整个字符串。

如果存储汉字,此时依然以字节解析,而不是以字符为单位。
如果开启了--raw选项:

此时汉字"好"截取了一半,但是不输出,只有"你"被完整拆分下来,才能解析。
SETRANGE
- 修改指定范围内的字符串
setrange key offset value
从下标offset位置开始覆盖,字符串替换为value,返回替换后的字符串长度。
示例:

此处从下标5,也就是字符w开始覆盖,往后三个字符替换为cpp,而ld不变。

如果字符串覆盖后超出原先的长度,此时字符串就会变长。
对于不存在的key:

如果在空的key后面修改字符串,此时offset之前的所有字节自动初始化为\x00,offset之后的内容正常覆盖。
总结:
| 命令 | 执行效果 | 
|---|---|
| set key value[key value...] | 设置 key的值为value | 
| get key | 获取 key的值 | 
| del key[key...] | 删除指定的 key | 
| mset key value[key value ...] | 批量设置指定的 key和value | 
| mget key[key...] | 批量获取 key的值 | 
| incr key | 指定的 整数的值+1 | 
| decr key | 指定的 整数的值-1 | 
| incrby key n | 指定的 整数的值+n | 
| decrby key n | 指定的 整数的值-n | 
| incrbyfloat key n | 指定的 整数/浮点数的值+n | 
| append key value | 指定的 字符串追加value | 
| strlen key | 获取指定 字符串的长度 | 
| setrange key offset value | 覆盖指定 字符串从offset开始的部分值 | 
| getrange key start end | 获取指定 字符串从start到end的部分值 | 
内部编码
在 Redis 中,string 数据类型的底层实现有三种编码方式:int、embstr 和 raw。每种编码方式有其特定的使用场景和实现细节,以优化内存使用和性能表现。
int
当一个字符串的值可以被解析为整数(有符号的 64 位整数范围内)时,
Redis会将其存储为整数
int 编码使用 8 byte 来存储整数值。这种方式的优势在于节省存储空间并提高处理速度,因为整数操作比字符串操作更高效。
embstr
用于存储长度小于或等于
39 byte的字符串。
embstr 编码是为了优化小字符串的内存分配和管理而设计的。embstr 的实现将字符串对象的结构和实际字符串数据放在一起,这样在创建时只需要一次内存分配。其包含一个 SDS(Simple Dynamic String)结构,用于管理字符串的长度等信息。
这种方式减少了内存碎片,提高了缓存的局部性,并使得创建和销毁字符串对象的速度更快。
raw
用于存储长度大于
39 byte的字符串。
raw 编码是传统方式,分开存储字符串对象和字符串数据。与 embstr 不同,raw 编码需要两次内存分配:一次用于存储字符串对象的基本信息,比如长度,另一次用于实际的字符串数据。
这种方式允许更灵活的字符串管理,适合处理较大字符串的场景。在需要对字符串进行修改时,raw 编码也能更好地管理内存。


![[20231103消息] 大模型商业化模式详解:烧钱之后如何挣钱?](https://img-blog.csdnimg.cn/img_convert/c5d7036bfc741c926ebcd9f732e45595.jpeg)
















