(一).概念
redis中的所有的key都是字符串,只不过value的类型时存在差异的。字符串类型的值实际上可以是字符串,包含了一般格式的字符串,或者类似JSON,XML格式的字符串,数字等等,甚至是二进制流数据。但是一个字符串的最大值不能超过512MB
(二).基础命令
1.常见命令
(1).set
将string类型的value设置到key中。如果key之前存在,则进行覆盖,无论原来的数据类型是什么。
语法:SET key value expiration EX seconds \| PX milliseconds NX\|XX
时间复杂度: O(1)
选项:
SET命令支持多种选项来影响它的行为:
EX seconds ,使用秒作为单位设置key的过期时间
PX milliseconds ,使用毫秒作为单位设置key的过期时间
NX ,只有key不存在的时候才进行设置,如果key之前已经存在,设置不执行
XX ,只有key存在的时候才进行设置,如果key之前不存在,设置不执行
返回值:
如果设置成功,则返回OK
如果由于SET指定了NX 或者 XX 但是条件不满足,SET不会执行,并返回 (nil)
示例






注意:这些带选项的命令我们可以用 SETNX SETEX PSETEX进行替代。


(2).get
获取key对应的value。如果key不存在,返回nil。如果value的数据类型不是string,则报错
时间复杂度:O(1)
返回值:key对应的value,如果key不存在,则返回nil


可以看到,当使用get命令获取list 的时候,报错了
(3).mget
一次性获取多个key的值。如果对应的key不存在或者对应的数据类型不是string,则返回nil
时间复杂度:O(N) N是key的数量
返回值:对应value的列表


由于key111的类型是list,所以返回nil
多次get 和 单次mget

可以看出,单词mget更节省带宽,向redis服务器请求的次数也少
(4).mset
一次性设置多个key的值
语法:mset key value key value ......
时间复杂度:O(N) N是key数量
返回值:返回OK

2.计数命令
(1).INCR
将key对应的string表示的数字加1 。如果key不存在,则视为key对应的value是0,如果key对应的string不是一个整型或者范围超过了64位有符号整型,则报错。
时间复杂度:O(1)
返回值:value加完之后的值




(2).INCRBY
将key对应的string表示的数字加上对应的值。如果key不存在,则视为key对应的value是0.如果key对应的string不是一个整型或者范围超过了64位有符号整型,则报错。
语法:incrby key decrement
时间复杂度:O(1)
返回值:value加完之后的数值



(3).DECR
将key对应的string表示的数字减1。如果key不存在,则视为key对应的value是0.如果key对应的string不是一个整数或者范围超过了64位有符号整型,则报错
语法:decr key
时间复杂度:O(1)
返回值:value减完之后的数值


(4).DECRBY
将key对应的string表示的数字减去对应的值。如果key不存在,则视为key对应的value是0.如果key对应的string不是一个整型或者范围超过了64位有符号整型,则报错。
decrby key decrement
时间复杂度:O(1)
返回值:value减完后的数值

(5).INCRBYFLOAT
将key对应的string表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是一个浮点数,则报错。允许使用科学计数法表示浮点数。
语法:incrbyfloat key increment
时间复杂度:O(1)
返回值:value加/减完后的数值

3.其他命令
(1).append
如果key已经存在并且是一个string,命令会将value追加到原有string的后面。如果key不存在,则效果等同于SET命令。
语法:append key value
时间复杂度:O(1) 追加的字符串的长度一般比较短
返回值:追加完成之后,string的长度


注意:Xshell终端,默认的字符编码是UTF8,在终端输入汉字之后,也就是按照utf8进行编码的,一个汉字在utf8中占3个字节
如果想要看到汉字,可以在启动的时候加一个 "--raw'"这样的选项,就可以使redis客户端能够自动的把二进制数据尝试翻译

(2).getrange
返回key对应的string的子串,由start和end确定(左闭右闭)。可以使用负数表示倒数。-1代表倒数第一个字符。超过范围的偏移量会根据string的长度调整成正确的值。
语法:getrange key start end
时间复杂度:O(N),N为start,end区间的长度,可以视为O(1)
返回值:string类型的字串



上述的代码,是强行切出了中间的一个字节,但是,切出的一个字节,在utf8码表上不知道能查出什么了,所以才乱码
(3).setrange
覆盖字符串的一部分,从指定的偏移开始
语法:setrange key offset value
时间复杂度:O(N),N为value的长度
返回值:替换后的stirng的长度

注意:setrange针对不存在的key,也是可以进行操作的,不过会把offset之前的内容填充成 0x00
(4).strlen
获取key对应的string的长度。当key存放的类型不是string时,则报错。
语法:strlen key
时间复杂度:O(1)
返回值:string的长度。如果key不存在时,返回0


(三).内部编码
字符串类型的内容编码有3种
int:8个字节的长整型
embstr:小于等于39个字节的字符串
raw:大于39个字节的字符串
Redis会根据当前值的类型和长度,动态决定使用哪种内部编码实现


注意:如果设置的是小数的话,本质上还是以字符串的形式进行存储的。这就意味着,每次进行算术预算,都需要把字符串转成小数,进行运算,然后将结果再转为字符串
(四).典型使用场景
1.缓存功能

应用服务器访问数据的时候,先查询Redis。如果Redis上数据存在了,就直接从Redis取数据交给应用服务器,不继续访问数据库了。如果Redis上数据不存在,再读取MySQL,把读到的结果,返回给应用服务器,同时,把这个数据也写入到Redis中。
但是,这样的策略,存在一个明显的问题。随着时间的推移,redis中的数据会越来越多,那么redis是否就会扛不住压力?
事实上,在把数据写给redis的同时,会给这个key设置一个过期时间。同时,Redis也会在内存不足的时候,提供淘汰策略
2.计数(Couter)功能
Redis可以实现快速计数,查询缓存的功能,同时,数据可以异步处理或者落地到其他数据源。

注意:这里的"异步的方式",指的是写入统计数据库的操作是异步的
3.共享会话(Session)
一个分布式Web服务将用户的Session信息,保存在各自的服务器中,但这样会造成一个问题,站在负载均衡的考虑,分布式服务会将用户的访问请求均衡到不同的服务器上,并且通常无法保证用户每次请求都会被均衡到同一台服务器上,这样当用户刷新依次访问是可能会发现需要重新登录。

为了解决这个问题,可以使用Redis将用户的Session信息进行集中管理,在这种模式下,只要保证Redis是高可用和可扩展的,无论用户被均衡到哪台Web服务器上,都集中从Redis中查询,更新Session信息

4.手机验证码
我们可以生成一个验证码,然后用户输入一下手机号,点击获取验证码,此时,可设置为"限制1分钟之内,最多获取5次验证码"或者"每次获取验证码必须间隔30秒"
在检查验证码的时候,把短信收到的验证码,提交到系统中,系统进行验证验证码是否正确
