本文系列学习redis五大常用数据类型之字符串String的基本操作及编码与底层数据结构
1. 基本操作
// set key value设置键值对
127.0.0.1:6379> set blog shenjian.online
OK
// get查询对应键值
127.0.0.1:6379> get blog
"shenjian.online"
// EX表示10秒后key过期
127.0.0.1:6379> set blog shenjian EX 10
OK
// PX表示1000毫秒后key过期
127.0.0.1:6379> set blog shenjian PX 1000
OK
// NX表示不存在key则设置,nil不成功
127.0.0.1:6379> set blog shenjian NX
(nil)
// XX表示存在key则设置,OK成功
127.0.0.1:6379> set blog shenjian XX
OK
127.0.0.1:6379> get blog
"shenjian"
// 向key值中追加.online字符串
127.0.0.1:6379> append blog .online
(integer) 15
// 获取key值长度
127.0.0.1:6379> strlen blog
(integer) 15
// 当key不存在时设置值,0设置失败
127.0.0.1:6379> setnx blog shenjian
(integer) 0
127.0.0.1:6379> set count 0
OK
// 增加1
127.0.0.1:6379> incr count
(integer) 1
// 减少1
127.0.0.1:6379> decr count
(integer) 0
// 当前key值加5
127.0.0.1:6379> incrby count 5
(integer) 5
// 当前key值减4
127.0.0.1:6379> decrby count 4
(integer) 1
127.0.0.1:6379> get count
"1"
// mset批量赋值
127.0.0.1:6379> mset name shenjian sex man
OK
// 批量获取值
127.0.0.1:6379> mget name sex other
1) "shenjian"
2) "man"
3) (nil)
// msetnx批量赋值,原子性,一个失败全部失败
127.0.0.1:6379> msetnx name zhangsan other 3
(integer) 0
127.0.0.1:6379> mget name other
1) "shenjian"
2) (nil)
// 获取字符串指定位置
127.0.0.1:6379> getrange name 0 3
"shen"
// 在指定位置开始替换值
127.0.0.1:6379> setrange name 0 hao
(integer) 8
127.0.0.1:6379> get name
"haonjian"
// 获取旧值同时设置新值
127.0.0.1:6379> getset name shenjian
"haonjian"
// 设置过期时间10秒,上面也出现过奥
127.0.0.1:6379> setex name 10 shenjian
OK
127.0.0.1:6379> ttl name
(integer) 8
2. 内部编码
127.0.0.1:6379> set name shenjianshenjianshenjianshenjianshenjianshen
OK
127.0.0.1:6379> strlen name
(integer) 44
127.0.0.1:6379> object encoding name
"embstr"
127.0.0.1:6379> set name shenjianshenjianshenjianshenjianshenjianshens
OK
127.0.0.1:6379> strlen name
(integer) 45
127.0.0.1:6379> object encoding name
"raw"
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> object encoding age
"int"
由上可以看出,当字节数少于等于44时,字符串编码为embstr,当大于44时,字符串编码为raw,对于整型编码为int
127.0.0.1:6379> set name shenjian
OK
127.0.0.1:6379> object encoding shenjian
(nil)
127.0.0.1:6379> append name shenjian
(integer) 16
127.0.0.1:6379> object encoding blog
"raw"
由上可以看出,redis中embstr实现为只读,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节
- embstr与raw都使用redisObject和sds保存数据
- embstr只分配一次内存空间,因此redisObject和sds[稍后介绍]是连续的
- raw需要分配两次内存空间,分别为redisObject和sds分配空间,不连续。
- embstr好处:创建/删除时少分配/释放一次空间,对象的所有数据连续,查找方便
- embstr坏处:当需要重新分配内存时,整个redisObject和sds都要重新分配空间,因此redis中的embstr实现为只读
3. 底层数据结构
String的数据结构为简单动态字符串(Simple Dynamic String,即SDS),是可以修改的字符串,采用预分配冗余空间的方式来减少内存的频繁分配。
当字符串长度小于1M时,扩容是加倍现有空间。超过1M,扩容只会多扩1M空间,字符串最大长度为512M