redis里的SDS数据类型
redis没有间接应用C语言里的字符串示意,而是本人构建名为简略动静字符串(simple dynamic string,SDS)的类型。在应用redis存储键值对时,不论值是什么类型,键的类型都是SDS,如果值是字符串类型时应用的就是SDS。
SDS的定义:
struct sdshdr { //记录buf数组中已应用字节的数量,也就是SDS字符串所保留字符串的长度 int len; //记录buf数组中未应用字节的数量 int free; //字节数组,用于保留字符串 char buf[];};
这个是在网上找的图,这里buf是char数组,我感觉应该是'R'|'e'|'d'|'i'|'s'|'\0'|才对,因为改不了在这里阐明一下。
- free属性值为0,示意这个SDS没有调配任何未应用空间。如果这个值不为0,则在'\0'前面则会调配有空的区域,其长度为free的值。
- len属性值为5,示意这个SDS保留了一个五字节长的字符串。
- buf属性一个char数组,前五个字节别离保留了'R'/'e'/'d'/'i'/'s',最初一个字节则保留了示意空字符的'\0'。
SDS遵循C字符串以空字符结尾的常规,保留空字符的1字节不计算在SDS的len属性里。
SDS较C语言字符串的长处
- 常数复杂度获取字符串长度。因为有len属性记录着属性已应用字符串长度,所以在应用STRLEN命令获取长度的时候复杂度为O(1);而C语言字符串获取的工夫复杂度为O(n)。
- 防止缓冲区溢出。SDS在进行批改或拼接前会查看空间是否满足批改所需长度,如果不够会进行扩容;而C语言没有长度查看会有溢出的可能。
- 缩小内存重调配次数。C语言在在进行字符串的增长或缩短操作时,须要对应的进行内存申请与开释,不然会有溢出或透露的可能;而内存的重调配是一个较耗时的操作,SDS采纳了空间预调配与惰性空间开释这两种优化策略。
- 二进制平安。C语言如果遇到空字符串时会被认为是字符串的完结,这使得其只能保留文本数据而像图片、视频文件等是没方法存储的;而SDS会以解决二进制的形式来解决寄存在buf数组里的数据
用表格总结下:
C字符串 | SDS |
---|---|
获取字符串长度工夫复杂度为O(n) | 获取字符串长度工夫复杂度为O(1) |
有缓冲区溢出危险 | 无溢出危险 |
批改字符串N次时肯定须要执行屡次内存生调配 | 批改字符串N次时最多须要执行屡次内存生调配 |
只能存文本 | 文本、图片、视频文件都能够存储 |