[redis] string

1、基础

常用命令

  • set key value:设定key持有指定的字符串value,如果该key存在则进行覆盖操作。总是返回”OK”。
  • get key:获取key的value。如果与该key关联的value不是String类型,redis将返回错误信息,因为get命令只能用于获取String value,如果该key不存在则返回null。
  • incr key:将指定的key的value递增1。如果该key不存在,会创建该key其初始value值为0,在incr之后其值为1。decr,incrby,decrby类似
  • decr key:将指定的key的value递减1。
  • incrby key step:将指定的key的value增加step
  • decrby key step:将指定的key的value减少step
  • append key value:如果该key存在,则在原有的value后拼接该值(字符串拼接);如果该key不存在,则重新创建一个key/value。
  • exists key :判断key是否存在
  • strlen key :获取key对应value的长度
  • getrange key 0 3,获取key对应value的截取字符串,下标范围为[0,3] ,[0,-1]代表整个字符串
  • setex key 30 “hello”:设置key 的值为 hello,30秒后过期
  • setnx key “redis” :如果key 不存在,创建key

2、底层实现:

Redis 虽然是用 C 语言写的,但是对于Redis的字符串,却不是 C 语言中的字符串(即以空字符’\0’结尾的字符数组),它是自己构建了一种名为 简单动态字符串(simple dynamic string,SDS)的抽象类型,并将 SDS 作为 Redis的默认字符串表示。

SDS 定义:

struct sdshdr{
     //记录buf数组中已使用字节的数量
     //等于 SDS 保存字符串的长度
     int len;
     //记录 buf 数组中未使用字节的数量
     int free;
     //字节数组,用于保存字符串
     char buf[];
}

用SDS保存字符串 “Redis”具体图示如下:
在这里插入图片描述
我们看上面对于 SDS 数据类型的定义:

  1. len 保存了SDS保存字符串的长度
  2. buf[] 数组用来保存字符串的每个元素
  3. free j记录了 buf 数组中未使用的字节数量

SDS的好处

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

  由于 len 属性的存在,我们获取 SDS 字符串的长度只需要读取 len 属性,时间复杂度为 O(1)。而对于 C 语言,获取字符串的长度通常是经过遍历计数来实现的,时间复杂度为 O(n)。

  1. 杜绝缓冲区溢出

  我们知道在 C 语言中使用 strcat 函数来进行两个字符串的拼接,一旦没有分配足够长度的内存空间,就会造成缓冲区溢出。而对于 SDS 数据类型,在进行字符修改的时候,会首先根据记录的 len 属性检查内存空间是否满足需求,如果不满足,会进行相应的空间扩展,然后在进行修改操作,所以不会出现缓冲区溢出。

  1. 减少修改字符串的内存重新分配次数

  C语言由于不记录字符串的长度,所以如果要修改字符串,必须要重新分配内存(先释放再申请),因为如果没有重新分配,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露。
  而对于SDS,由于len属性和free属性的存在,对于修改字符串SDS实现了空间预分配和惰性空间释放两种策略:
  1、空间预分配:对字符串进行空间扩展的时候,扩展的内存比实际需要的多,这样可以减少连续执行字符串增长操作所需的内存重分配次数。
  2、惰性空间释放:对字符串进行缩短操作时,程序不立即使用内存重新分配来回收缩短后多余的字节,而是使用 free 属性将这些字节的数量记录下来,等待后续使用。(当然SDS也提供了相应的API,当我们有需要时,也可以手动释放这些未使用的空间。)

  1. 二进制安全

  因为C字符串以空字符作为字符串结束的标识,而某些内容可能包括空字符串,因此C字符串无法正确存取;例如字符串"abc"在C语言中存储的是"abc\0",但是如果此时有个字符串"abc\0de",这个时候C语言仍然认为这个是"abc"。而SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。

  1. 兼容部分 C 字符串函数

  虽然 SDS 是二进制安全的,但是一样遵从每个字符串都是以空字符串结尾的惯例,这样可以重用 C 语言库<string.h> 中的一部分函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值