Redis常见数据类型(1)String
字符串类型是 Redis
最基础的数据类型,关于字符串需要特别注意:
- 首先
Redis
中所有的键的类型都是字符串类型,而且其他几种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型,所以字符串类型能为其他 4 种数据结构的学习奠定基础. - 其次,字符串类型的值实际可以是字符串,包含⼀般格式的字符串或者类似 JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚至是⼆进制流数据,例如图片、音频、视频等。不过⼀个字符串的最大值不能超过 512 MB
由于 Redis 内部存储字符串完全是按照⼆进制流的形式保存的,所以 Redis 是不处理字符集编码问题的,客⼾端传入的命令中使用的是什么字符集编码,就存储什么字符集编码
常见命令
命令 | 执行效果 | 时间复杂度 |
---|---|---|
set key value[key value…] [EX seconds] [NX | XX] | 设置key的值为value,可选参数包括过期时间,条件 | O(1) |
get key | 获取指定的key的值 | O(1) |
del key [key…] | 删除指定的key | O(k),k是键的个数 |
mset key value [key value…] | 批量设置指定的key和value | O(k),k是键的个数 |
mget key [key…] | 批量获取key的值 | O(k),k是键的个数 |
incr key | 指定的key值+1 | O(1) |
decr key | 指定的key值-1 | O(1) |
incrby key n | 指定的key值 + n | O(1) |
decrby key n | 指定的key值+n | O(1) |
incrbyfloat key n | 指定的key值+n | O(1) |
append key value | 指定的key追加value | O(1) |
strlen key | 获取指定key的长度 | O(1) |
setrange key offset value | 覆盖指定key的从offset开始的部分值 | O(n),n是字符串长度,通常视为O(1) |
getrange key start end | 获取指定的key的从start到end的部分值 | O(n),n是字符串长度,通常视为O(1) |
SET
将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖,无论原来的数据类型是什么。之前关于此 key 的 TTL 也全部失效.
set key value [expiration ex seconds | px milliseconds] [nx | xx]
时间复杂度: O(1)
选项:
-
EX seconds ⸺ 使用秒作为单位设置 key 的过期时间
-
PX milliseconds ⸺ 使用毫秒作为单位设置 key 的过期时间
-
NX ⸺ 只在 key 不存在时才进行设置,即如果 key 之前已经存在,设置不执行
-
XX ⸺ 只在 key 存在时才进行设置,即如果 key 之前不存在,设置不执行
如果设置成功,返回OK
如果由于 SET 指定了 NX 或者 XX 但条件不满足,SET 不会执行,并返回 (nil)
GET
获取 key 对应的 value。如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错
get key
时间复杂度:O(1)
返回值:key对应的value,或者nil(当key不存在)
MGET
⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil
mget key [key…]
时间复杂度:O(N) N 是 key 数量
返回值:对应 value 的列表
MSET
一次性设置多个key的值
mset key value [key value…]
时间复杂度:O(N) N 是 key 数量
返回值:永远是 OK
学会使用批量操作,可以有效提高业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是无节制的,否则可能造成单⼀命令执行时间过长,导致 Redis 阻塞
SETNX
设置 key-value 但只允许在 key 之前不存在的情况下
setnx key value
时间复杂度:O(1)
返回值:1 表示设置成功。0 表示没有设置
INCR
将 key 对应的 string 表示的数字加⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错
incr key
时间复杂度:O(1)
返回值:integer 类型的加完后的数值
INCRBY
将 key 对应的 string 表示的数字加上对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错
incrby key decrement
时间复杂度:O(1)
返回值:integer 类型的加完后的数值
DECR
将 key 对应的 string 表示的数字减⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错
decr key
时间复杂度:O(1)
返回值:integer 类型的减完后的数值
DECRBY
将 key 对应的 string 表示的数字减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错
decrby key decrement
时间复杂度:O(1)
返回值:integer 类型的减完后的数值
INCRBYFLOAT
将 key 对应的 string 表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的不是 string,或者不是⼀个浮点数,则报错。允许采用科学计数法表示浮点数
incrbyfloat key increment
时间复杂度:O(1)
返回值:加/减完后的数值
APPEND
如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key 不存在,则效果等同于 SET 命令
append key value
时间复杂度:O(1). 追加的字符串⼀般长度较短, 可以视为 O(1).
返回值:追加完成之后 string 的长度
GETRANGE
返回 key 对应的 string 的子串,由 start 和 end 确定(左闭右闭)。可以使用负数表示倒数。-1 代表倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据 string 的长度调整成正确的值
getrange key start end
时间复杂度:O(N). N 为 [start, end] 区间的长度. 由于 string 通常比较短, 可以视为是 O(1)
返回值:string 类型的子串
SETRANGE
覆盖字符串的⼀部分,从指定的偏移开始
setrange key offset value
时间复杂度:O(N), N 为 value 的长度. 由于⼀般给的 value 比较短, 通常视为 O(1).
返回值:替换后的 string 的长度
STRLEN
获取 key 对应的 string 的长度。当 key 存放的类似不是 string 时,报错
strlen key
时间复杂度:O(1)
返回值:string 的长度。或者当 key 不存在时,返回 0
内部编码
字符串类型的内部编码有3中:
- int : 8个字节的长整型
- embstr: 小于等于39个字节的字符串
- raw: 大于39个字节的字符串
使用场景
缓存(Cache)功能:
典型的缓存使用场景,其中 Redis
作为缓冲层,MySQL
作为存储层,绝大部分请求的数据都是从 Redis
中获取。由于 Redis
具有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用
计数(Count)功能
许多应用都会使用 Redis
作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源
共享会话(Session)
⼀个分布式 Web 服务将用户的 Session 信息(例如用户登录信息)保存在各自的服务器中,但这样会造成⼀个问题:出于负载均衡的考虑,分布式服务会将用户的访问请求均衡到不同的服务器上,并且通常无法保证用户每次请求都会被均衡到同⼀台服务器上,这样当用户刷新⼀次访问是可能会发现需要重新登录,这个问题是用户无法容忍的
手机验证码
很多应用出于安全考虑,会在每次进行登录时,让用户输入手机号并且配合给手机发送验证码,然后让用户再次输入收到的验证码并进行验证,从而确定是否是用户本人。为了短信接口不会频繁访问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过 5 次