Redis学习之旅 String篇
String 支持追加,截取,自增,位图等等玩法,大佬们都快把Redis的String玩出花了,本篇总结下Redis 的String 类型
认识type/ object encoding命令
先看下type命令的帮助文档,它说这个命令可以确定一个已存储的Key的类型
可以看到无论输入什么样的数据,字符串也好,数字串也好,他显示的type都是string
但是通过对象编码命令查看,就会看到,Redis在类型之外 ,还单独的维护了一个编码格式
进行编码的好处在于,可以在做数学运算时,直接读取编码格式就能确认这个能不能进行计算,减去了类型检查的开销
换个玩法,调用append命令向一个数字追加另一个数字,它就变成了raw格式,那么这个格式还能运算么?
答案是可以的,所以在执行一些方法的时候,其实是会改变它隐藏的编码类型
接下来打算按照Redis的版本发展,总结一下到6.0版本的所有的String命令
通过 help @string 可以查看redis支持的所有String 类型的命令,也可以通过Redis官网查看命令支持
1.0时代
命令列表
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
DECR | 1.0.0 | Value减一 | DECR key |
DECRBY | 1.0.0 | Value减去decrement | DECRBY key decrement |
GET | 1.0.0 | 获取Key对应的Value | GET key |
GETSET | 1.0.0 | 把Value修改为新值,同时返回旧值 | GETSET key value |
INCR | 1.0.0 | Value加一 | INCR key |
INCRBY | 1.0.0 | Value加上increment | INCRBY key increment |
MGET | 1.0.0 | 同时获取几个K的值,至少一个Key | MGET key [key …] |
MSET | 1.0.1 | 批量向几个Key写入Value,至少提供一对 | MSET key value [key value …] |
MSETNX | 1.0.1 | 同MSET命令,但是有个条件 所有Key均不存在的情况下才可以写成功 | MSETNX key value [key value …] |
SET | 1.0.0 | 写入一个Value | SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL] |
SETNX | 1.0.0 | 只有Key不存在时才可以写入成功 | SETNX key value |
关注点
1.0时代命令不多,有一个NX(SETNX MSETNX)命令需要注意,它可以提供不存在写入,存在返回写入失败的功能,因此常被用来实现分布式锁,但是它有个致命问题,不可以在setnx的时候写入过期时间,因此容易出现问题
SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
从Redis2.6.12开始,SET命令支持了众多的参数
- EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value
- PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
- NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
- XX :只在键已经存在时,才对键进行设置操作。
- KEEPTTL: 暂时不知道,有知道的小伙伴可以留言 ,谢谢
SET 测试
- 设置不存在的值和设置已存在的值,无论值存在不存在 ,都返回OK
- 使用NX命令设置一个存在的Key和不存在的Key
- 使用XX命令设置一个存在的Key和不存在的Key
- 对Key设置超时时间,在超时前查询一次,超时后查询一次
2.0时代
命令列表
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
APPEND | 2.0.0 | 向String 后追加字符 | APPEND key value |
BITCOUNT | 2.6.0 | 计算给定字符串中,被设置为 1 的比特位的数量 | BITCOUNT key [start end] |
BITOP | 2.6.0 | 对一个或多个保存二进制位的字符串 key 进行位运算 | BITOP operation destkey key [key …] |
BITPOS | 2.8.7 | 返回位图中第一个值为bit的二进制位的位置 | BITPOS key bit [start] [end] |
GETBIT | 2.2.0 | 对 key 所储存的字符串值,获取指定偏移量上的位 | GETBIT key offset |
GETRANGE | 2.4.0 | 获取字符串指定范围的数 | GETRANGE key start end |
INCRBYFLOAT | 2.6.0 | 对Value进行浮点相加运算 | INCRBYFLOAT key increment |
PSETEX | 2.6.0 | 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间, 而不是像 SETEX 命令那样,以秒为单位 | PSETEX key milliseconds value |
SETBIT | 2.2.0 | 对 key 所储存的字符串值,设置或清除指定偏移量上的位 | SETBIT key offset value |
SETEX | 2.0.0 | 设置Value的超时时间,单位为秒 | SETEX key seconds value |
SETRANGE | 2.2.0 | 按位置对字符进行替换 | SETRANGE key offset value |
STRLEN | 2.2.0 | 获取字符的长度 | STRLEN Key |
浮点计算、字符串偏移、位图
2.0时代的更新,主要是添加了浮点计算、字符串偏移计算以及大量的位操作命令
浮点计算
通过下面的测试可以确定
- 类似于几点几这类数字,在Redis里是计为String 类型的,对"浮点类"的Value调用 INCR DECR会报错
- 浮点运算必须通过INCRBYFLOAT进行计算,运算结果都会标记为String
- 如果计算结果正好是整数,不会带上 几点零的结果,会去掉小数点,可以对整数结果进行INCR DECR
字符串偏移
STRLEN
这个方法可以查看字符长度(编码长度),Redis不对数据进行任何的编码,将所有的String看成一个个的字节拼凑而成,这也是为什么我们在使用Redis时,需要去设置对象的序列化与反序列化配置
第一个“哈哈”是UTF-8编码,UTF-8中中文占三个字节,因此两个字算6个字节,第二个“哈哈”则是GBK编码,因此占4个字节长度
APPEND
向Key追加字符串,如果字符串不存在,则创建
GETRANGE
- 如果不设置start 和end 是会报错的
- 如果你的start 大于end 会返回空字符串
- 正向索引是从0开始的
- 逆向索引是从-1开始的(废话,0被占用了)
- 索引越界也不会报错,会返回空串
SETRANGE
SETRANGE比较尿性
- 如果你向一个不存在的Key写值,它会在你的offset前面补上0
- 如果你向一个已存在的Key写值,会覆盖索引区间内的字符
- 如果向已存在的Key写值,且索引越界,中间的空缺填0
位运算
位运算牵扯内容太多,单独开一章来写 《Redis学习之旅 位图(BitMap)》
3.0时代
命令列表
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
BITFIELD | 3.2.0 | 把Redis字符串当作位数组,并能对变长位宽和任意未字节对齐的指定整型位域进行寻址 | BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] |
这个也是位运算相关内容,一并合入上方的位运算专题中
4.0 5.0无新增API
6.0 时代
命令列表
命令 | 起始版本 | 作用 | 示例 |
---|---|---|---|
STRALGO | 6.0.0 | 针对字符串运行算法(当前为LCS) | STRALGO LCS algo-specific-argument [algo-specific-argument …] |
6.0新版本添加的功能之一,要了解这个功能,先得了解下LCS是干啥的
- LCS(Longest Common Subsequence),最长公共子串问题,将字符串去掉某几个字符后得到的串称为自己的子串,找到两个字符串之间 匹配的最长公共子串,就是LCS算法解决的问题
- 举例 有两个字符串 myabctext thisismytext, 第一个字符串在移除abc后,得到一个子串 mytext ,另一个字符串在移除thisis后,得到子串mytext,则它们的最长公共子串为mytext,没有比这个更长的子串了