乐趣区

关于redis:redis学习之一SDS

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 次时最多须要执行屡次内存生调配
只能存文本 文本、图片、视频文件都能够存储
退出移动版