Redis数据类型-String-基本使用和原理

命令使用

命令描述时间复杂度
APPEND key value命令将 value 追加到 key 原来的值的末尾平摊O(1)
BITCOUNT key [start] [end]计算给定字符串中,被设置为 1 的比特位的数量O(N)
BITOP operation destkey key [key …]对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkeyO(N)
DECR keykey 中储存的数字值减一O(1)
DECRBY key decrementkey 所储存的值减去减量 decrementO(1)
GET key返回 key 所关联的字符串值O(1)
GETBIT key offsetkey 所储存的字符串值,获取指定偏移量上的位(bit)O(1)
GETRANGE key start end返回 key 中字符串值的子字符串,字符串的截取范围由 startend 两个偏移量决定(包括 startend 在内)O(N), N 为要返回的字符串的长度。长度不大时为O(1)
GETSET key value将给定 key 的值设为 value ,并返回 key 的旧值(old value)O(1)
INCR keykey 中储存的数字值增一(可以做计数器、限速器)O(1)
INCRBY key incrementkey 所储存的值加上增量 incrementO(1)
INCRBYFLOAT key incrementkey 中所储存的值加上浮点数增量 incrementO(1)
MGET key [key …]返回所有(一个或多个)给定 key 的值O(N) , N 为给定 key 的数量
MSET key value [key value …]同时设置一个或多个 key-valueO(N), N 为要设置的 key 数量
MSETNX key value [key value …]同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在O(N), N 为要设置的 key 的数量
PSETEX key milliseconds value这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位O(1)
SET key value [EX seconds] [PX milliseconds] [NX XX]将字符串值 value 关联到 keyO(1)
SETBIT key offset valuekey 所储存的字符串值,设置或清除指定偏移量上的位(bit)O(1)
SETEX key seconds value将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)O(1)
SETNX key valuekey 的值设为 value ,当且仅当 key 不存在O(1)
SETRANGE key offset valuevalue 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始对小(small)的字符串,平摊复杂度O(1)。否则为O(M), Mvalue 参数的长度
STRLEN key返回 key 所储存的字符串值的长度O(1)

数据类型

Redis是由C语言编写,在C语言中没有String的类型,所以用自定义的数据类型SDS(simple dynamic string),并将SDS作为Redis的字符串表示。

SDS在旧版本中使用方式跟新版本不同,如果你看到如下描述都是旧版本:

struct sdshdr{
    int len;        // SDS所保存的字符串的长度 
    int free;       // buf数组中未使用的字节的数量 
    char buf[];     // 字节数组,用于保存字符串(大小等于 len+free+1) 
};

根据不同的长度的字符串定义了不同的结构,分别为:sdshdr5sdshdr8sdshdr16sdshdr32sdshdr64

在这里插入图片描述

  • flags 标志位,主要是识别这是sdshdr几,目前只用了3位,还有5位空余
  • len 指的是字符串的长度(已使用空间大小)
  • alloc 总共可用的字符空间大小,应该是实际buf的大小减1(因为c字符串末尾必须是\0,不计算在内)
  • buf[ ] 指的是就是一个普通的字符串数组,用来实际存储的

说明:redis在做初始化时,如果长度小于3的使用sdshdr5,小于2^8的长度使用sdshdr8,以此类推

空间分配

原理:数据在进行扩容的时候,往往会申请一个更大的数组,然后把数据复制进去。为了提升性能,在分配空间的时候不能分配一个刚刚好的空间,而是要分配一个更大的空间。

C语言采用N+1的字符数组来表示字符串,且末尾置’\0’;

相较于C原生的字符串,sds多了len、alloc、flag三个字段来存储一些额外的信息,redis考虑到了字符串拼接时带来的巨大损耗,所以每次新建sds的时候会预分配一些空间来应对未来的增长。

C获取字符串长度的时间复杂度为O(n),须全部遍历,SDS只需读取计算len字段即可,且因为预分配了额外的空间杜绝了缓存溢出和减少了修改字符串时的内存分配次数,且sds是以len判断字符串结尾中间是否出现’\0’与其无关,是二进制安全的。

SDS的好处就是通过预分配内存和维护字符串长度,实现动态字符串

策略

  • 初始:按照当前字符串长度计算并+1bit
  • 增加:新增长new len = len + add len(增加部分的长度)
    • 若 new len 小于1M,则SDS分配的内存大小为 (2*new len)+1bit
    • 若new len 大于1M,则SDS分配的内存大小为 newlen + 1M +1bit
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值