Redis字符串详解
redis虽然是使用c语言实现的,但是它并没有直接使用c语言提供的字符串,char[]和char*。而是自己实现的动态字符串类型(simple dynamic string),简称(sds)
struct sdshdr{
int len; // 空间总长度
int free; // 剩余空间长度
char[] buf; // 字符数组
}
sds和c语言字符串的相同点:
- sds字符串末尾也会以' '结束,len不会将' '计算在长度之内,
- 都是使用了char[]存储字符串
sds和c语言字符串区别:
- sds可以直接通过len获取到字符串长度,时间复杂度为O(1),c语言需要通过便利字符数组,时间复杂度为O(n)
- sds在添加字符串是会自动判断free是否足够,如果不够自动扩容,c语言添加字符串需要自己手动开辟内存空间,如果目标字符串空间不满足添加后的字符串长度,那么会导致缓冲区溢出
使用sds的优势:
- sds会降低空间分配次数,提高内存使用率
- 空间预分配:sds自动扩容后,会进行空间预分配,如果len < 1M,则会分配与len相同的空间给free,如果len >= 1M,则会分配1M给free
- 惰性空间回收:sds删除自己某一部分字符串时,不会立即回收这一块的空间,而是在下一次空间不够时再进行回收
Redis中的字符串有三种编码: raw
、embstr
、int
embstr:短字符串和浮点数,int是整数字符串,raw是可变且任意长度字符串
通过OBJECT ENCODING <key>
即可查看字符串编码
命令详解
-
SET:设置一个字符串,
SET <key> <value> [EX 过期时间(s)] [PX 过期时间(ms)] [NX(不存在时设置)|XX(存在时设置)]
,EX
和PX
不能同时设置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编码)