一、基本用法

字符串是redis中的基本数据类型之一,能存储任何形式的字符串,包括二进制数据。同时,它还可以进行字符串运算数据运算位运算等操作。一个字符串最大能有512M。

字符串主要的操作命令有两个:

  • GET KEY: 如果KEY存在就返回对应的值,如果不存在则返回空值nil
  • SET KEY VALUE: 给KEY设置值为VALUE,如果KEY已经存在则更新值。

例如:

# 设置一个新值
127.0.0.1:6379> set test HelloWorld
OK
# 获取值
127.0.0.1:6379> get test
"HelloWorld"
# 获取不存在的值返回nil
127.0.0.1:6379> get aaaa
(nil)

字符串也支持同时给多个key同时赋值,方法为:

  • MGET key value [key value]: 同时设置多个键值。
  • MSET key value [key value]: 同时获取多个键值。
127.0.0.1:6379> mset keya aaa keyb bbb keyc ccc
OK
127.0.0.1:6379> mget keya keyb keyc
1) "aaa"
2) "bbb"
3) "ccc"

还有一个常用的操作就是在获取key的同时并设置key的值:

  • GETSET key value:给key赋值并返回先前的元素,如果元素不存在返回nil
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> getset k 123
(nil)
127.0.0.1:6379> getset k 456
"123"

二、操作API

字符串主要有以下操作命令:

2.1. APPEND

在尾部增加字符串,命令格式:append key value,成功将会返回添加后的字符串长度。

127.0.0.1:6379> set test Hello
OK
127.0.0.1:6379> append test World
(integer) 10  # 添加成功返回总长度
127.0.0.1:6379> get test
"HelloWorld"

2.2. STRLEN

获取字符串长度,命令格式:strlen key,成功将会返回该值得长度。

127.0.0.1:6379> strlen test
(integer) 10
127.0.0.1:6379> strlen aaaa
(integer) 0  # 键不存在返回0

2.3. GETRANGE

获取指定偏移范围内的字符,命令格式:getrange key start end,键不存在返回空。

127.0.0.1:6379> getrange test 5 10
"World"
127.0.0.1:6379> getrange aaaa 1 2
""  # 键不存在返回空

和大多数程序语言一样,redis的字符串下标从0开始,到len(key) - 1结束。要注意的是redis中可以使用-1表示最后一位。

127.0.0.1:6379> getrange test 0 -1 # 获取第一个字符到最后一个字符
"HelloWorld"

三、数据运算

当我们存入一个十进制整数或者浮点数到redis当中去的时候,redis会自动察觉到这一点,并允许我们使用相关的命令来操作它们。

3.1 INCR和DECR

把整形数据加一或者减一,命令格式:incr key decr key,执行成功会返回增加过后的值,如果key不存在时会自动创建。

127.0.0.1:6379> set num 100
OK
127.0.0.1:6379> incr num
(integer) 101  
127.0.0.1:6379> incr num
(integer) 102
127.0.0.1:6379> decr num
(integer) 101
127.0.0.1:6379> get num
"101"
127.0.0.1:6379> incr aaaa
(integer) 1  # 自动创建aaaa并初始化值为0然后+1

3.2 INCRBY、DECRBY和INCRBYFLOAT

增加或者删除指定的大小,命令格式为:incrby key incrementINCRBYDECRBY针对整数,INCRBYFLOAT针对浮点数,不可以使用INCRBYDECRBY操作浮点数。

127.0.0.1:6379> set num 100
OK
127.0.0.1:6379> incrby num 10
(integer) 110
127.0.0.1:6379> decrby num 5
(integer) 105
127.0.0.1:6379> incrbyfloat num 1.1
"106.1"
127.0.0.1:6379> incrby num 10
(error) ERR value is not an integer or out of range  # 使用整形命令操作浮点数会报错

使用数据运算的同时还可以字符串命令:

127.0.0.1:6379> set num 100
OK
127.0.0.1:6379> append num 999  # 在尾部添加
(integer) 6
127.0.0.1:6379> get num
"100999"
127.0.0.1:6379> incr num  # 仍然可以执行数据运算
(integer) 101000

除了这些以外,redis还支持位运算,可参考:Redis中的位运算

四、实现原理

字符串内部使用了三种编码方式,分别是int/raw/embstr。

4.1 int编码

当存储的字符串是一个整形数据的时候,redis会自动以整形数据来保存。

127.0.0.1:6379> set mobile 10086
OK
127.0.0.1:6379> OBJECT ENCODING mobile
"int"

当使用int类型编码的时候,字符串对象结构为:

4.2 raw和embstr编码

raw和embstr编码底层都是使用sdshdr来存储字符串,使用raw方式编码的字符串对象结构:

embstr和raw编码的不同在于使用embstr编码的时候,redis会把上面的redisObject和shshdr作为一个对象同时申请内存,它们在内存上是连续的,而raw编码的字符串在内存上并不连续。

当存储的字符串长度小于39时,redis会使用embstr来编码。这样做的目的主要有以下几个:

  1. 减少内存的分配和释放次数
  2. 内存连续适合小对象缓存
最后修改:2020 年 03 月 14 日
喜欢就给我点赞吧