Redis核心数据结构之SDS(一)

数据结构与对象

简单动态字符串

概述

Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,简称C字符串),而是自己构建了一种名为简单动态字符串(Simple Dynamic String, SDS)的后向类型,并将SDS用作Redis的默认字符串表示。在Redis里面C字符串只会作为字符串字面量(string literal)用在一些无须对字符串值进行修改的地方。比如打印日志。

当Redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串时,Redis就会使用SDS来表示字符串值,比如在Redis的数据库里面,包含字符串值的键值对在底层都是由SDS来实现的

除了用来保存数据库中的字符串值之外,SDS还被用作缓冲区(buffer):AOF模块中的AOF缓冲区、以及客户端状态中的输入缓冲区,都是由SDS实现的

定义

每个sds.h/sdshdr结构表示一个SDS值如图.

SDS遵循C字符串以空字符结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性里面,并且为空字符分配额外的1字节空间,以及添加空字符到字符串末尾等操作,都是由SDS函数自动完成的,所以这个空字符对于SDS的使用者来说是完全透明的。遵循空字符结尾这一惯例

的好处是,SDS可以直接重用一部分C字符串函数库里的函数,例如printf函数,

c 复制代码
printf("%s", s->buf)

来打印SDS保存的字符串值"Redis",而无需为SDS编写专门的打印函数

  • 1.free属性的值为0,表示这个SDS没有分配任何未使用空间
  • 2.len属性的值为5,表示这个SDS保存了一个5字节长的字符串
  • 3.buf属性是一个char类型的数组,数组的前5个字节分为保存了
    'R'、'e'、'd'、'i'、's'五个字符,最后一个字节则保存了空字符'\0'

    这个SDS和上面的SDS的区别在于,这个SDS为buf数组分配了5字节未使用空间,所以它的free属性的值为5

SDS与C字符串的区别

根据传统,C语言使用长度为N+1的字符串数组来表示长度为N的字符串,并且字符数组的最后一个元素总是空字符'\0',如图所示。

C语言使用的这种简单的字符串表示方式,并不能满足Redis对字符串在安全性、效率性以及功能方面的要求

1.常数复杂度获取字符串长度

因为C字符串并不记录自身的长度信息,所以为了获取一个C字符串的长度,程序必须遍历整个字符串,对遇到的每个字符进行计数,知道遇到代表字符串结尾的空字符为止,这个操作的复杂度为O(N)。

和C字符串不同,因为SDS在len属性中记录了SDS本身的长度,所以获取一个SDS长度的复杂读仅为O(1).设置和更新SDS长度的工作是由SDS的API在执行时自动完成,使用SDS无须进行任何手动修改长度的工作,通过SDS而不是C字符串,Redis将获取字符串长度所需的复杂度从O(N)降低到了O(1),这确保了获取字符串长度的工作不会

成为Redis的性能瓶颈。例如,因为字符串键在底层使用SDS来实现,所以即使我们对一个非常长的字符串键反复执行STRLEN命令,也不会对系统性能造成任何影响,因为STRLEN命令的复杂度仅为O(1)

相关推荐
Highcharts.js3 小时前
教程:基于 React + Highcharts 构建一个单页应用程序、按需数据拉取与图表渲染
开发语言·前端·数据结构·react.js·前端框架·highcharts·页面应用
海兰3 小时前
【数据库】tdsql(mysql8.0)优化思考三
数据库·redis
煎饼学大模型4 小时前
Agent 的“大脑-手“解耦架构:当推理层和工具执行层各自独立演进
数据库·人工智能·oracle·架构·agent
muddjsv7 小时前
SQLite数据库文件机制详解:journal、wal、shm文件作用与备份避坑
数据库·sqlite
稚南城才子,乌衣巷风流8 小时前
动态开点:原理、实现与应用场景
数据结构·算法
吴声子夜歌9 小时前
MongoDB 4.2——应用程序设计
数据库·mongodb
数字新视界9 小时前
动环监控可视化在数据中心管理中的应用与实践解析
数据库·物联网·解决方案·动环监控·大榕树
极地野狼 音乐哔哔9 小时前
数据库备份恢复的原理实践
数据库
yyds_yyd_100869 小时前
1464. 数组中两元素的最大乘积(2026.07.27)
数据结构·c++·算法·leetcode
互联网中的一颗神经元9 小时前
小白python入门 - 25. SQL 与表设计入门
数据库·python·sql