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)

相关推荐
LucianaiB31 分钟前
【金仓数据库征文】_AI 赋能数据库运维:金仓KES的智能化未来
运维·数据库·人工智能·金仓数据库 2025 征文·数据库平替用金仓
时序数据说1 小时前
时序数据库IoTDB在航空航天领域的解决方案
大数据·数据库·时序数据库·iotdb
.生产的驴1 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
AnsenZhu1 小时前
2025年Redis分片存储性能优化指南
数据库·redis·性能优化·分片
阿让啊1 小时前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
oydcm2 小时前
MySQL数据库概述
数据库·mysql
oioihoii2 小时前
C++23中if consteval / if not consteval (P1938R3) 详解
java·数据库·c++23
草莓啵啵~2 小时前
搜索二叉树-key的搜索模型
数据结构·c++
带娃的IT创业者2 小时前
《AI大模型趣味实战》基于RAG向量数据库的知识库AI问答助手设计与实现
数据库·人工智能
李菠菜3 小时前
非SpringBoot环境下Jedis集群操作Redis实战指南
java·redis