前言
下表中包含本博客提到的所有命令
字符串类型是 Redis 最基础的数据类型,关于字符串需要特别注意:
1)⾸先 Redis 中所有的键(key)的类型都是字符串类型,⽽且其他⼏种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型,所以字符串类型能为其他数据结构的学习奠定基础。
2)其次,如下图所示,字符串类型的值包含⼀般格式的字符串或者类似 JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚⾄是⼆进制流数据,例如图⽚、⾳频、视频等。不过⼀个字符串的最⼤值不能超过 512 MB。
3)Redis 中的 String 类型,直接是按照二进制数据的格式存储的,没有涉及到任何的编码转换,存的是什么取出来的还是什么,所以 Redis 出现乱码的概率很小
常见命令
SET 设置键值对
将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖原来的 value 值,⽆论原来的数据类型是什么。之前关于此 key 的 TTL 也全部失效。
语法:
java
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)
GET 获取 value 值
获取 key 对应的 value。如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错。
语法:
java
GET key
时间复杂度:O(1)
返回值:key 对应的 value,或者 nil 当 key 不存在。
MSET ⼀次性设置多个 key 的值
⼀次性设置多个 key 的值。
语法:
java
MSET key value [key value ...]
时间复杂度:O(N) N 是 key 数量
返回值:永远是 OK
MGET ⼀次性获取多个 key 的值
⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil
语法:
java
MGET key [key ...]
时间复杂度:O(N) N 是 key 数量
多次 get vs 单次 mget
Redis 是客户端-服务器 结构的程序,所以在命令行输入的每条命令都会被 Redis 构造成 HTTP 请求发送给服务器,服务器接收到请求根据请求的内容,将要返回的数据构造成 HTTP 响应返回
所以当我们要获取多个数据时,采用 get 命令多次获取,就会构造多个 HTTP 请求,接收多个 HTTP 响应,而采用 mget 命令一次获取所有的数据,就只会构造一个 HTTP 请求,返回一个 HTTP 响应
很显然,使用 mget 命令批量获取数据的方式可以节省很多的网络资源
· 但也不能批量的获取太多的数据,要有节制,如果一次性批量获取太多的数据,就会导致该命令的执行时间过长,而 Redis 是单线程的程序,当前命令执行时间过长就会导致后面的命令没有时间执行,就会导致客户端迟迟得不到响应,造成客户端阻塞
SETNX,SETEX,PSETEX
SETNX 等同于 SET KEY VALUE NX 只在 key 不存在时才进⾏设置,即如果 key 之前已经存在,设置不执⾏
SETEX 等同于 SET KEY VALUE EX 在设置键值对的同时设置秒级过期时间
PSETEX 等同于 SET KEY VALUE PX 在设置键值对的同时设置毫秒级过期时间
时间复杂度:O(1)
返回值:1 表⽰设置成功。0 表⽰没有设置。
计数命令
INCR 将数字加 1
将 key 对应的 value 表⽰的数字加⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 string 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
至于为什么 value 是 String 类型,但却能对保存的数字类型进行计算,是因为底层的编码存储数字用的是 int ,关于 Redis 各个类型底层编码的具体实现推荐看Redis 的数据结构和内部编码【雨林优选】【面试重点】
语法:
java
INCR key
时间复杂度:O(1)
返回值:integer 类型的数据加完后的数值
INCRBY 将数字加指定的值
将 key 对应的 value 表⽰的数字加上对应的值。如果 key 不存在,则视为 key 对应的 value是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
java
INCRBY key decrement
时间复杂度:O(1)
返回值:integer 类型的数据加完后的数值。
当然如果加的值是负数,就能得到减法的效果
DECR 将数字减 1
将 key 对应的 value 表示的数字减⼀。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
java
DECR key
时间复杂度:O(1)
返回值:integer 类型的数据减完后的数值。
DECRBY 将数字减指定的值
将 key 对应的 value 表⽰的数字减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的 value 不是⼀个整型或者范围超过了 64 位有符号整型,则报错。
语法:
java
DECRBY key decrement
时间复杂度:O(1)
返回值:integer 类型的数据减完后的数值。
当然如果减的值是负数,就能得到加法的效果
INCRBYFLOAT 将浮点数加指定的值
将 key 对应的 value 表⽰的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果 key 不存在,则视为 key 对应的 value 是 0。如果 key 对应的不是 string 类型,或者不是⼀个浮点数,则报错。允许采⽤科学计数法表⽰浮点数。
语法:
java
INCRBYFLOAT key increment
时间复杂度:O(1)
返回值:加/减完后的数值。
其他命令
APPEND 追加字符串
如果 key 已经存在并且是⼀个 string,命令会将 value 追加到原有 string 的后边。如果 key不存在, 则效果等同于 SET 命令。
语法:
java
APPEND KEY VALUE
时间复杂度:O(1).
追加的字符串⼀般⻓度较短,可以视为 O(1).
返回值:追加完成之后 value 的⻓度。
GETRANGE 获取子串
返回 key 对应的 value 的⼦串,由 start 和 end 确定(左闭右闭)。可以使⽤负数表⽰倒数。-1 代表倒数第⼀个字符,-2 代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据string 的⻓度调整成正确的值。
语法:
java
GETRANGE key start end
时间复杂度:O(N).N 为 [start, end] 区间的⻓度.由于 string 通常⽐较短, 可以视为是 O(1)
返回值:string 类型的⼦串
注意当键值对中存的数据是中文时,如果获取子串不当就会出现一定的问题
解释:由于博主使用的 xshell 软件的编码方式是 utf8 ,所以一个中文字符由 3 个字节表示,而 GETRANGE 获取子串操作的单位是字节,所以上述的例子就截去了第一个和最后一个字节,因此导致第一个中文字符和最后一个中文字符无法正常表示
当我们截去前三个字节和后三个字节就成功去除了'你' 和 '界' 两个中文字符
提醒:一个中文字符由多少个字节组成不是固定的,要看具体的编码方式
SETRANGE 覆盖字符串
覆盖字符串的⼀部分,从指定的偏移开始。
语法:
java
SETRANGE key offset value
时间复杂度:O(N),N 为 value 的⻓度.由于⼀般给的 value ⽐较短, 通常视为 O(1).
返回值:替换后的 string 的⻓度。
STRLEN 获取字符串长度
获取 key 对应的 value 的⻓度。当 key 存放的类型不是 string 时,报错。
语法:
java
STRLEN key
时间复杂度:O(1)
返回值:string 的⻓度。或者当 key 不存在时,返回 0。