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语言字符串的长处

  1. 常数复杂度获取字符串长度。因为有len属性记录着属性已应用字符串长度,所以在应用STRLEN命令获取长度的时候复杂度为O(1);而C语言字符串获取的工夫复杂度为O(n)。
  2. 防止缓冲区溢出。SDS在进行批改或拼接前会查看空间是否满足批改所需长度,如果不够会进行扩容;而C语言没有长度查看会有溢出的可能。
  3. 缩小内存重调配次数。C语言在在进行字符串的增长或缩短操作时,须要对应的进行内存申请与开释,不然会有溢出或透露的可能;而内存的重调配是一个较耗时的操作,SDS采纳了空间预调配与惰性空间开释这两种优化策略。
  4. 二进制平安。C语言如果遇到空字符串时会被认为是字符串的完结,这使得其只能保留文本数据而像图片、视频文件等是没方法存储的;而SDS会以解决二进制的形式来解决寄存在buf数组里的数据

用表格总结下:

C字符串SDS
获取字符串长度工夫复杂度为O(n)获取字符串长度工夫复杂度为O(1)
有缓冲区溢出危险无溢出危险
批改字符串N次时肯定须要执行屡次内存生调配批改字符串N次时最多须要执行屡次内存生调配
只能存文本文本、图片、视频文件都能够存储