Redis字符串详解

Redis字符串详解

redis虽然是使用c语言实现的,但是它并没有直接使用c语言提供的字符串,char[]和char*。而是自己实现的动态字符串类型(simple dynamic string),简称(sds)

struct sdshdr{
    int len;	// 空间总长度
    int free;	// 剩余空间长度
    char[] buf;	// 字符数组
}

sds和c语言字符串的相同点:

  1. sds字符串末尾也会以''结束,len不会将''计算在长度之内,
  2. 都是使用了char[]存储字符串

sds和c语言字符串区别:

  1. sds可以直接通过len获取到字符串长度,时间复杂度为O(1),c语言需要通过便利字符数组,时间复杂度为O(n)
  2. sds在添加字符串是会自动判断free是否足够,如果不够自动扩容,c语言添加字符串需要自己手动开辟内存空间,如果目标字符串空间不满足添加后的字符串长度,那么会导致缓冲区溢出

使用sds的优势:

  1. sds会降低空间分配次数,提高内存使用率
  2. 空间预分配:sds自动扩容后,会进行空间预分配,如果len < 1M,则会分配与len相同的空间给free,如果len >= 1M,则会分配1M给free
  3. 惰性空间回收:sds删除自己某一部分字符串时,不会立即回收这一块的空间,而是在下一次空间不够时再进行回收

Redis中的字符串有三种编码: rawembstr int

embstr:短字符串和浮点数,int是整数字符串,raw是可变且任意长度字符串

通过OBJECT ENCODING <key>即可查看字符串编码

命令详解

  • SET:设置一个字符串,SET <key> <value> [EX 过期时间(s)] [PX 过期时间(ms)] [NX(不存在时设置)|XX(存在时设置)]EXPX不能同时设置

    SET a abc		// 不设置过期时间和条件
    SET a abc EX 5	        // 5秒钟过期
    SET a abc PX 5000	// 5000毫秒过期
    SET a abc NX		// 不存在时设置
    SET a abc XX		// 存在时设置
    
  • SETNX:当key不存在时设置,SET <key> <value>,相当于SET <key> <value> NX

  • SETEX:设置key过期时间并设置新值,SETEX <key> <过期时间(s)> <value>,相当于SET <key> <value> <EX 过期时间(s)>

  • PSETEX:命令和SETEX一样,只不过时间单位是毫秒

  • GET:获取字符串值,GET <key>

    SET a abc
    GET a	// abc
    
  • GETSET:获取并设置新值,GETSET <key> <value>

    SET a abc
    GETSET a def	// abc
    GET a		// def
    
  • STRLEN:获取字符串长度,STRLEN <key>

    SET a abc
    STRLEN a	// 3
    
  • APPEND:添加字符串到当前key指向的字符串末尾,APPEND <key> <value>

    SET a abc
    APPEND a " edf"
    GET a	// abc edf
    
  • SETRANGE:从指定位置开始修改原来字符串的值,字符串下标从0开始,SETRANGE <key> <offset> <replaceValue>

    SET a abc
    SETRANGE a 0 00
    GET a	// 00c
    
  • GETRANGE:返回指定范围的字符串,-1代表字符串最后位置,GETRANGE <key> <start> <end>

    SET a abc
    GETRANGE a 0 -1	// abc
    
  • INCR:让int编码字符串自增1,INCR <key>

    SET a 1
    INCR a
    GET a	// 2
    
  • INCRBY:让int编码字符串加上指定数值,INCRBY <key> <addValue>

    SET a 1
    INCRBY a 2
    GET a	// 3
    
  • INCRBYFLOAT:让浮点数加上指定数值,如果对int编码使用,会被转换成embstr编码,INCRBYFLOAT <key> <addValue>

    SET a 1
    OBJECT ENCODING a	// int 
    INCRBYFLOAT a 3.8
    OBJECT ENCODING a	// embstr
    GET a	// 4.8
    
  • DECR:int编码字符串自减,DECR <key>

    SET a 2
    DECR a
    GET a	// 1
    
  • DECRBY:int编码减去指定值,和INCRBY用法一样

  • MSET:一次性设置多个字符串,MSET <key> <value> [key value ..]

    MSET a a1 b b1 c c1
    
  • MGET:一次性获取多个字符串,MGET <key> [key ..]

    MGET a b c	// a1 b1 c1
    
  • MSETNX:设置多个字符串,如果有一个key已存在,则拒绝设置所有字符串,MSETNX <key> <value> [key value ..]

    SET a a1
    MSETNX b b1 c c1		// ok
    KEYS *					// a b c
    
    DEL b c
    MSETNX a a1 b b1 c c1	// fail
    KEYS *					// a
    

embstr、int、raw的转换机制

  • APPEND命令会把int和embstr编码转成raw
  • embstr编码的字符串在长度大于44时会被转换成raw编码
  • INCRBYFLOAT命令会将整数类型转成浮点型(embstr编码)
原文地址:https://www.cnblogs.com/dagger9527/p/12980205.html