Redis string字符串

1年前 (2024-04-28)
string(字符串)是 Redis 中最简单的数据类型。我们知道,Redis 所有数据类型都是以 key 作为键,通过检索这个 key 就可以获取相应的 value 值。Redis 存在多种数据类型,比如字符串、列表、哈希散列等,它们对应的 value 结构各不相同。本节先讲解字符串的相关知识。

认识Redis字符串

Redis 使用标准 C 语言编写,但在存储字符时,Redis 并未使用 C 语言的字符类型,而是自定义了一个属于特殊结构 SDS(Simple Dynamic  String)即简单动态字符串),这是一个可以修改的内部结构,非常类似于 Java 的 ArrayList。

1) SDS动态字符串

SDS 的结构定义如下:

struct sdshdr{

//记录buf数组中已使用字符的数量,等于 SDS 保存字符串的长度

int len;

//记录 buf 数组中未使用的字符数量

int free;

//字符数组,用于保存字符串

char buf[];

从上述结构体可以看出,Redis string 将字符串存储到字符类型的buf[]中,并使用 lenfreebuf[]数组的长度和未使用的字符数进行描述。

下图展示了 SDS 字符串的结构示意图:

redis string结构

图1


上图 1 存储了一个len为 4 的 “java\0”字符串,并且未使用的字符数free为 0。你可能注意到 buf 数组存储的字符串仍然以 C语言字符格式的“\0”结尾的,这样做的目的是为了能够重用 C语言库 <string.h> 中的部分函数。

在 C语言中,字符串类型的结尾以空字符串 ‘\0’来标识的。但在某些情况下,字符串可能会包含具有实际意义的“空字符”,此时 C语言就无确的存取这个字符了,而 Redis 通过 len 来标识字符串的总长度,从而保证了数据的二进制安全特性。

2) 分配冗余空间

string 采用了预先分配冗余空间的方式来减少内存的频繁分配,如下图所示:

Redis string原理

图2


如图 2 所示,Redis 每次给 string 分配的空间都要大于字符串实际占用的空间,这样就在一定程度上了 Redis string 存储的效率,比如当字符串长度变大时,无需再重新申请内存空间。

3) string自动扩容

当字符串所占空间小于 1MB 时,Redis 对字符串存储空间的扩容是以成倍的方式增加的;而当所占空间超过 1MB 时,每次扩容只增加 1MB。Redis 字符串允许的值字节数是 512 MB。

Redis字符串令

1) 令格式

Redis 提供了操作字符串的令,通过学习这些令我们可以掌握如何使用它们,其语法格式如下:

redis 127.0.0.1:6379> COMMAND KEY_NAME

  • COMMAND:表示字符串的令;

  • KEY_NAME:表示 key(键)的名称。


在练习令的过程中,大家要善于利用 Redis 客户端给出的自动语法提示,比如SET令的格式如下:

127.0.0.1:6379> SET key value [EX seconds|PX milliseconds] [NX| ]

其中[]内代表可选参数,其含义如下所示:
  • EX seconds:设置指定的过期时间,以秒为单位;

  • PX milliseconds:设置指定的过期时间,以毫秒为单位;

  • NX:先判断 key 是否存在,如果 key 不存在,则设置 key 与 value;

  • :先判断 key 是否存在,如果 key 存在,则重新设置 value。


SET令演示:在 key 不存在的情况下设置过期时间为 60s:

#key的过期时间为60s,过期后自动删除

redis 127.0.0.1:6379> SET www.biancheng网站站点" rel="nofollow" />

redis 127.0.0.1:6379> GETRANGE KEY_NAME start end

注意,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内的闭区间)

示例如下:

127.0.0.1:6379> SET website www.biancheng网站站点" rel="nofollow" />

127.0.0.1:6379> GETSET num first

"6"

127.0.0.1:6379> GETSET num second

"first"

#查看长度值

127.0.0.1:6379> strlen num

(integer) 6

注意:num 之前存储的值为“6”,所以结果返回“6”。

3) SETEX令

将值 value 存储到 key 中 ,并将 key 的过期时间设为 seconds (以秒为单位)。示例如下:

#设置过期时间为60s

127.0.0.1:6379> SETEX www.biancheng网站站点" rel="nofollow" />

#返回0,说明令执行失败

127.0.0.1:6379> MSETNX www.biancheng网站站点" rel="nofollow" />

redis 127.0.0.1:6379> SETRANGE KEY_NAME OFFSET VALUE

  • KEY_NAME:指 key 的名字;

  • OFFSET:指初始偏移量;

  • VALUE:指要替换成的字符串。 


示例如下: 

127.0.0.1:6379> SET word "hello world"

OK

127.0.0.1:6379> SETRANGE word 6 www.biancheng网站站点" rel="nofollow" />