Redis(一)-redis基本数据类型string(简单动态字符串SDS)

redis数据类型概述

Redis数据库由键值对组成,每个键值对都是由对象组成的,键为字符串对象,值可以为字符串对象、list列表对象,哈希对象hash、集合对象set、有序集合sorted set。

redis-SDS

sds-概述

Redis没有使用C语言传统的字符串表示,而是自己构建了一种简单动态字符串,作为redis的默认字符串表示。Redis中,c字符串只会作为字符串字面量(用在一些无需对值进行改变的地方)。其他时候会使用SDS来表示字符串值。例如set msg ”aa“将会创建键值对,键为msg字符串的SDS,值为aa字符串的SDS。例如rpush fruits ”apple“  ”banana“将会创建一个键值对对象,键为fruits字符串的SDS,值为三个SDS的列表对象。AOF的缓冲区中也有SDS的应用。

sds-定义

Redis由c实现,sds主要包含三个部分,free未使用空间长度,len长度、buf为char型数组,保存数据,最后一个字符为空字符\0,不计入len。这样设计的好处是可以使用一些c的原生操作方法。

                                              

redis底层使用c实现,那么为什么没有使用c字符串而是使用SDS呢?

 

    1.优化了获取字符串长度

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

而对于SDS,获取字符串长度为O(1),维护SDS操作的api由其自身进行,无需操作。

    2.杜绝缓冲区溢出

由于c字符串不记录自身长度,那么当用户执行修改字符串操作时,忘了给新的变量分配足够的空间。那么就会造成缓冲区溢出。

                       

而对于SDS来说,完全不需要考虑溢出的问题。当执行修改操作时,SDS会先检查SDS空间是否满足修改所需的要求,如果不满足会自动将SDS的空间进行扩展。

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

C字符串每次修改都需要重分配内存空间来满足新的字符串需要。Redis为了避免这种情况成为性能的瓶颈,因此做了优化。

   字符串变长时,空间预分配

当SDS字符串变长时,那么除了要为sds分配修改所需要的空间,那么还会为sds分配额外的未使用空间。当下次增长时,先检查未使用空间是否满足需求,满足则会直接使用未使用空间。分配规则:SDS长度(len的值)小于1M时,程序分配和len属性同样大小的未使用空间;SDS长度大于1M时,分配1M的未使用空间。

通过预分配,SDS将连续增长N次所需的内存重分配次数从必定N次降低为最多N次。

   当字符串变短时,惰性空间释放

   SDS变短时将会将释放出的空间放到未使用空间中待下次使用。

  4.可以保存二进制数据

C语言字符串以空字符判断是否结尾,那么将会不适合存储带空格的数据。

SDS不存在此问题,长度有len属性进行判断。因此sds可以保存任意长度的数据。

  5.兼容部分c字符串函数

延续了c字符串以空字符结尾的习惯,那么将会重用一部分<string.h>库中的部分函数,完成重用的目的。

sds与c字符串区别总结

相关面试问题:redis底层使用c实现,那么为什么没有使用c字符串而是使用SDS呢?

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值