Redis 数据类型--> 字符串解析

闲来无事,去看了下《Redis 设计与实现》这本广受好评的书(确实好,连我这种小白都读得顺畅)。

Redis 中的字符串

Redis 中的字符串并没有直接使用 C 语言中的字符串,而是自己构建了一种简单动态字符串,并将 SDS 用作 Redis 的默认字符串表示。

举个列子,客户端执行命令:resdis> SET msg "hello word",其中:

  • 键值对的键是一个字符串对象,对象的底层实现是一个保存着字符串 “msg” 的 SDS。
  • 键值对的值也是一个字符串对象,对象的底层实现是一个保存着字符串 “hello word” 的 SDS。

SDS 的定义

比如一个 “Redis” 字符串,其 SDS 结构如图(图片来自书中):
在这里插入图片描述


SDS 与 C 字符串的区别:


一、O(1) 时间复杂度获取字符串长度

众所周知,C 或 Java 要或者字符串的长度,都要跑去把字符串遍历一遍了才知道,而 SDS 结构的 len 属性就存了字符串的长度,可以直接获取。

二、杜绝缓冲区溢出

举个列子,比如你要向 “Redis” 这个字符串中拼接一个字符串,在 C 语言中,如果你忘了提前为 “Redis” 分配足够的空间,那么在拼接后会导致新拼接的内容被意外的修改。而 SDS 的空间分配策略完全杜绝了这种情况,当 SDS API 需要对 SDS 进行修改时, API 会检查 SDS 空间是否够用,不够的话会自动去扩容。
在这里插入图片描述

三、减少修改字符串时带来的内存重分配次数

在 C 中,无论你对字符串进行拼接或删减都会要重新分配内存,很繁琐,而 SDS 使用了两种优化策略:空间预分配和惰性空间释放。

1、空间预分配

当 SDS 的 API 对一个 SDS 进行修改,并且需要对 SDS 进行空间扩展的时候,程序不仅会为 SDS 分配所够用的空间,还会为 SDS 分配额外的未使用空间。
在这里插入图片描述
举个例子,字符串 “Redis” 的 SDS 结构:
在这里插入图片描述
在给它拼接一个字符串 “Cluster” 时,会重新进行一次内存分配,将 len 修改成13字节,并将未使用空间 free 同样修改为13字节:
在这里插入图片描述
这时候我们如果还想再拼接一个字符串 “Tutorial” 时,由于未使用空间 free 里的13字节足够使用了,就不需要再重新分配内存。

2、惰性空间释放

对字符串 “XYXaYYbcXYYY” 执行sdstrim(s,"XY)" // 移除 字符串中所有的 “X” 和 “Y”
在这里插入图片描述
在移除后,会多出来8个字节,而这8个字节会作为未使用空间 free 保留在 SDS 里,如果后面还要对此字符串进行拼接操作的话,这个 free 就又派上用场了。
在这里插入图片描述
在这里插入图片描述

四、二进制安全

五、兼容部分 C 字符串函数


总结:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值