命令 | 描述 | 时间复杂度 |
---|---|---|
APPEND key value | 命令将 value 追加到 key 原来的值的末尾 | 平摊O(1) |
BITCOUNT key [start] [end] | 计算给定字符串中,被设置为 1 的比特位的数量 | O(N) |
BITOP operation destkey key [key …] | 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上 | O(N) |
DECR key | 将 key 中储存的数字值减一 | O(1) |
DECRBY key decrement | 将 key 所储存的值减去减量 decrement | O(1) |
GET key | 返回 key 所关联的字符串值 | O(1) |
GETBIT key offset | 对 key 所储存的字符串值,获取指定偏移量上的位(bit) | O(1) |
GETRANGE key start end | 返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内) | O(N), N 为要返回的字符串的长度。长度不大时为O(1) |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value) | O(1) |
INCR key | 将 key 中储存的数字值增一(可以做计数器、限速器) | O(1) |
INCRBY key increment | 将 key 所储存的值加上增量 increment | O(1) |
INCRBYFLOAT key increment | 为 key 中所储存的值加上浮点数增量 increment | O(1) |
MGET key [key …] | 返回所有(一个或多个)给定 key 的值 | O(N) , N 为给定 key 的数量 |
MSET key value [key value …] | 同时设置一个或多个 key-value 对 | O(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 关联到 key | O(1) |
SETBIT key offset value | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit) | O(1) |
SETEX key seconds value | 将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位) | O(1) |
SETNX key value | 将 key 的值设为 value ,当且仅当 key 不存在 | O(1) |
SETRANGE key offset value | 用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始 | 对小(small)的字符串,平摊复杂度O(1)。否则为O(M), M 为 value 参数的长度 |
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)
};
根据不同的长度的字符串定义了不同的结构,分别为:sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64
说明: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的好处就是通过预分配内存和维护字符串长度,实现动态字符串