一、基本用法
字符串运算、数据运算和位运算
字符串主要的操作命令有两个:
- : 如果
KEY
存在就返回对应的值,如果不存在则返回空值nil
。 -
: 给
KEY
设置值为VALUE
,如果KEY
例如:
1 2 3 4 5 6 7 8 9 |
# 设置一个新值 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]
: 同时获取多个键值。
1 2 3 4 5 6 |
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的值:
- :给
key
赋值并返回先前的元素,如果元素不存在返回nil
1 2 3 4 5 6 |
27.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
,成功将会返回添加后的字符串长度。
1 2 3 4 5 6 |
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
,成功将会返回该值得长度。
1 2 3 4 |
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
,键不存在返回空。
1 2 3 4 |
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表示最后一位。
1 2 |
127.0.0.1:6379> getrange test 0 -1 # 获取第一个字符到最后一个字符 "HelloWorld" |
三、数据运算
当我们存入一个十进制整数或者浮点数到redis当中去的时候,redis会自动察觉到这一点,并允许我们使用相关的命令来操作它们。
3.1 INCR和DECR
把整形数据加一或者减一,命令格式:incr key
decr key
,执行成功会返回增加过后的值,如果key不存在时会自动创建。
1 2 3 4 5 6 7 8 9 10 11 12 |
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 increment
。INCRBY
和DECRBY
针对整数,INCRBYFLOAT
针对浮点数,不可以使用INCRBY
和DECRBY
操作浮点数。
1 2 3 4 5 6 7 8 9 10 |
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 # 使用整形命令操作浮点数会报错 |
使用数据运算的同时还可以字符串命令:
1 2 3 4 5 6 7 8 |
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 |
四、实现原理
字符串内部使用了三种编码方式,分别是int/raw/embstr。
4.1 int编码
当存储的字符串是一个整形数据的时候,redis会自动以整形数据来保存。
1 2 3 4 |
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来编码。这样做的目的主要有以下几个:
- 减少内存的分配和释放次数
- 内存连续适合小对象缓存
评论