Redis
支持 5
种数据结构:
string
(字符串)list
(列表)hash
(字典)set
(集合)zset
(有序集合)
Redis
所有的数据结构都是以唯一的key
字符串作为名称,通过这个key
来获取相应的value
数据。
5
种数据结构是指value
的不同结构。
1 string(字符串)
Redis
没有直接使用 C
语言中的传统字符串,而是自己构建了一种名为 简单动态字符串(simple dynamic string, SDS) 的抽象类型。
在
Redis
中,C
语言字符串只会用在那些不需要对字符串进行修改的地方,也就是作为 字符串字面量,例如打印日志的地方。
SDS
作为Redis
中默认字符串的表示,无论是key
还是value
,需要的时候都是使用的SDS
。另外,SDS
还被用作缓冲区(buffer
)。
1.1 SDS 的实现
Redis
中通过 sdshdr
结构表示 SDS
:
struct sdshdr {
// 表示SDS字符串的长度。注意:可以小于buf[]长度
int len;
// 记录buf[]数组中未使用字节的数量
int free;
// 字节数组,用于保存字符串
char buf[];
}
下图描述了 SDS
的数据结构:
buf[]
是一个 char
类型的数组,最后一个字节保存空字符 \0
。
空字符 \0
没有计入 SDS
长度中。
遵循
C
字符串以空字符结尾的惯例,好处是可以直接重用C
字符串函数库中的函数。
1.2 SDS的优点
下面列出了 SDS
相较于 C
字符串的优点:
- 获取字符串长度复杂度为
O(1)
因为 C
字符串并不记录自身长度,所以获取长度的复杂度为 O(n)
;而 SDS
在 len
中记录了字符串长度,所以复杂度为 O(1)
。
- 拼接字符串不会导致缓冲区溢出
因为 SDS
在拼接字符串之前会检查 SDS
空间是否满足要求,如果空间不够会自动扩容,所以不会导致缓冲区溢出的问题。
- 能够减少内存重分配次数
SDS
通过 空间预分配、惰性空间释放 策略来减少内存重分配次数,优化性能。
-
空间预分配策略优化
SDS
字符串增长的操作:当字符串增长时&#