redis—String字符串
目录
前言
字符串类型是Redis最基础的数据类型,关于字符串需要特别注意: 1)首先Redis中所有的键的类型都是字符串类型,而且其他几种数据结构也都是在字符串类似基础.上构建的,例如列表和集合的
 元素类型是字符串类型,所以字符串类型能为其他4种数据结构的学习奠定基础。2) 其次,如图2-7所示,字符串类型的值实际可以是字符串,包含-般格式的字符串或者类似JSON、XML 格式的字符串;数字,可以是整型或者浮点型;甚至是二进制流数据,例如图片、音频、视频等。不过一个字符串的最大值不能超过512 MB。
由于Redis内部存储字符串完全是按照二进制流的形式保存的,所以Redis是不处理字符集
 编码问题的,客户端传入的命令中使用的是什么字符集编码,就存储什么字符集编码。
1.字符串数据类型

2.常见命令
SET
 将string类型的value设置到key中。如果key之前存在,则覆盖,无论原来的数据类型是什么。之
 前关于此key的TTL也全部失效。
 语法:
SET key value [expiration EX seconds|PX milliseconds] [NX|XX] 命令有效版本: 1.0.0之后
 时间复杂度: 0(1)
 选项:
 SET命令支持多种选项来影响它的行为:
 EX seconds一使用秒作为 单位设置key的过期时间。
 PX milliseconds 一使用毫秒作为 单位设置key的过期时间。
 NX —只在key不存在时才进行设置,即如果key之前已经存在,设置不执行。
 XX一只在key存在时才进行设置,即如果key之前不存在,设置不执行。
 注意:由于带选项的SET命令可以被SETNX、SETEX、 PSETEX 等命令代替,所以之后的版本
 中,Redis 可能进行合并。
 返回值:
 ●如果设置成功,返回OK。.
 ●如果由于SET指定了NX或者XX但条件不满足,SET不会执行,并返回(nil)。
 示例:
redis> EXISTS mykey
(integer) 0
redis> SET mykey "Hello"
OK
redis> GET mykey
"Hello"
redis> SET mykey "World" NX
(nil)
redis> DEL mykey
(integer) 1
redis> EXISTS mykey
(integer) 0
redis> SET mykey "World" XX
(nil)
redis> GET mykey
(nil)
redis> SET mykey "World" NX
OK
redis> GET mykey
"World"
redis> SET mykey "Will expire in 10s" EX 10
OK
redis> GET mykey
"Will expire in 10s"
redis> GET mykey # 10秒之后
(nil)GET
 获取key对应的value。如果key不存在,返回nilo如果value的数据类型不是string,会报错。
 语法:
GET KEY命令有效版本: 1.0.0之后
 时间复杂度: O(1)
 返回值: key 对应的value,或者nil当key不存在。
 示例:
redis> GET nonexisting
(nil)
redis> SET mykey "Hello"
"OK"
redis> GET mykey
"Hello"
redis> DEL mykey
(integer) 1
redis> EXISTS mykey
(integer) 0
redis> HSET mykey name Bob
(integer) 1
redis> GET mykey
(error) WRONGTYPE Operation against a key holding the wrong kind of valueMGET
 一次性获取多个 key的值。如果对应的key不存在或者对应的数据类型不是string,返回nilo
 语法:
MGET key [key ...] 命令有效版本: 1.0.0之后
 时间复杂度: O(N) N是key数量
 返回值:对应value的列表
 示例:
redis> SET key1 "Hello"
"OK"
redis> SET key2 "World"
"OK"
redis> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)MSET
 一次性设置多个key的值。
 语法:
MSET key value [key value ...] 命令有效版本: 1.0.1 之后
 时间复杂度: O(N) N是key数量
 返回值:永远是OK
 示例:
redis> MSET key1 "Hello" key2 "World"
"OK"
redis> GET key1
"Hello"
redis> GET key2
"World"图2-8多次get vs单次mget:

如图2-8所示,使用mget / mset由于可以有效地减少了网络时间,所以性能相较更高。假设网络耗
 时1毫秒,命令执行时间耗时0.1毫秒,则执行时间如表2-2所示。
表2-21000次get和1次mget对比:

学会使用批量操作,可以有效提高业务处理效率,但是要注意,每次批量操作所发送的键的数量也不是无节制的,否则可能造成单一命令执行时间过长,导致Redis阻塞。
SETNX
 设置key-value但只允许在key之前不存在的情况下。
 语法:
SETNX key value 命令有效版本: 1.0.0之后
 时间复杂度: 0(1)
 返回值: 1表示设置成功。0表示没有设置。
 示例:
redis> SETNX mykey "Hello"
(integer) 1
redis> SETNX mykey "World"
(integer) 0
redis> GET mykey
"Hello"SET、SET NX和SET XX的执行流程如图2-9所示。
 图2-9SET、SET NX、SET XX执行流程

INCR
 将key对应的string表示的数字加- -。如果key不存在,则视为key对应的value是0。如果key对
 应的string不是一个整型或者范围超过了64位有符号整型,则报错。
 语法:
INCR key命令有效版本: 1.0.0之后
 时间复杂度: O(1)
 返回值: integer 类型的加完后的数值。.
 示例:
redis> EXISTS mykey
(integer) 0
redis> INCR mykey
(integer) 1
redis> SET mykey "10"
"OK"
redis> INCR mykey
(integer) 11
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> INCR mykey
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> INCR mykey
(error) value is not an integer or out of rangeINCRBY
 将key对应的string表示的数字加上对应的值。如果key不存在,则视为key对应的value是0。如
 果key对应的string不是一个整型或者范围超过了64 位有符号整型,则报错。
 语法:
INCRBY key decrement 命令有效版本: 1.0.0 之后
 时间复杂度: O(1)
 返回值: integer 类型的加完后的数值。
 示例:
redis> EXISTS mykey
(integer) 0
redis> INCRBY mykey 3
(integer) 3
redis> SET mykey "10"
"OK"
redis> INCRBY mykey 3
(integer) 13
redis> INCRBY mykey "not a number"
(error) ERR value is not an integer or out of range
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> INCRBY mykey 3
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> INCRBY mykey 3
(error) value is not an integer or out of rangeDECR
 将key对应的string表示的数字减- -。如果key不存在,则视为key对应的value是0。如果key对
 应的string不是一个整型或者范围超过了64位有符号整型,则报错。
 语法:
DECR key 命令有效版本: 1.0.0之后
 时间复杂度: O(1)
 返回值: integer 类型的减完后的数值。
 示例:
redis> EXISTS mykey
(integer) 0
redis> DECR mykey
(integer) -1
redis> SET mykey "10"
"OK"
redis> DECR mykey
(integer) 9
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> DECR mykey
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> DECR mykey
(error) value is not an integer or out of rangeDECYBY
 将key对应的string表示的数字减去对应的值。如果key不存在,则视为key对应的value是0。如
 果key对应的string不是一个整型或者范围超过了64位有符号整型,则报错。
 语法:
DECRBY key decrement命令有效版本: 1.0.0之后
 时间复杂度: O(1)
 返回值: integer 类型的减完后的数值。
 示例:
redis> EXISTS mykey
(integer) 0
redis> DECRBY mykey 3
(integer) -3
redis> SET mykey "10"
"OK"
redis> DECRBY mykey 3
(integer) 7
redis> DECRBY mykey "not a number"
(error) ERR value is not an integer or out of range
redis> SET mykey "234293482390480948029348230948"
"OK"
redis> DECRBY mykey 3
(error) value is not an integer or out of range
redis> SET mykey 'not a number'
"OK"
redis> DECRBY mykey 3
(error) value is not an integer or out of rangeINCRBYFLOAT
 将key对应的string表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果
 key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是一个浮点数,则报
 错。允许采用科学计数法表示浮点数。
 语法:
INCRBYFLOAT key increment 命令有效版本: 2.6.0之后
 时间复杂度: O(1)
 返回值:加/减完后的数值。
 示例:
redis> SET mykey 10.50
"OK"
redis> INCRBYFLOAT mykey 0.1
"10.6"
redis> INCRBYFLOAT mykey -5
"5.6"
redis> SET mykey 5.0e3
"OK"
redis> INCRBYFLOAT mykey 2.0e2
"5200"很多存储系统和编程语言内部使用CAS机制实现计数功能,会有一定的CPU开销,但在Redis中完全不存在这个问题,因为Redis是单线程架构,任何命令到了Redis服务端都要顺序执行。
APPEND
 如果key已经存在并且是一个string,命令会将value追加到原有string的后边。如果key不存在,
 则效果等同于SET命令。
 语法:
APPEND KEY VALUE 命令有效版本: 2.0.0 之后
 时间复杂度: O(1).追加的字符串-般长度较短, 可以视为O(1).?
 返回值:追加完成之后string的长度。
 示例:
redis> EXISTS mykey
(integer) 0
redis> APPEND mykey "Hello"
(integer) 5
redis> GET mykey
"Hello"
redis> APPEND mykey " World"
(integer) 11
redis> GET mykey
"Hello World"GETRANGE
 返回key对应的string的子串,由start和end确定(左闭右闭)。可以使用负数表示倒数。-1 代表倒数第一个字符, -2代表倒数第二个,其他的与此类似。超过范围的偏移量会根据string的长度调整成正确的值。
 语法:
GETRANGE key start end 命令有效版本: 2.4.0之后
 时间复杂度: O(N). N为[start, end]区间的长度.由于string通常比较短,可以视为是O(1)
 返回值: string 类型的子串
 示例:
redis> SET mykey "This is a string"
"OK"
redis> GETRANGE mykey 0 3
"This"
redis> GETRANGE mykey -3 -1
"ing"
redis> GETRANGE mykey 0 -1
"This is a string"
redis> GETRANGE mykey 10 100
"string"SETRANGE
 覆盖字符串的一部分,从指定的偏移开始。
 语法:
SETRANGE key offset value命令有效版本: 2.2.0之后
 时间复杂度: O(N), N为value的长度.由于一般给的value比较短,通常视为0(1).
 返回值:替换后的string的长度。
 示例:?
redis> SET key1 "Hello World"
"OK"
redis> SETRANGE key1 6 "Redis"
(integer) 11
redis> GET key1
"Hello Redis"STRLEN?
 获取key对应的string的长度。当key存放的类似不是string时,报错。
 语法:
STRLEN key 命令有效版本: 2.2.0之后
 时间复杂度: O(1)
 返回值: string 的长度。或者当key不存在时,返回0。
 示例:
redis> SET mykey "Hello world" 1
"OK"
redis> STRLEN mykey
(integer) 11
redis> STRLEN nonexisting
(integer) 0命令小结
 表2-3是字符串类型命令的效果、时间复杂度,开发人员可以参考此表,结合自身业务需求和数
 据大小选择合适的命令。
字符串类型命令小结:

内部编码
 字符串类型的内部编码有3种:
 ●int: 8个字节的长整型。
 ●embstr:小于等于39个字节的字符串。
 ●raw:大于39个字节的字符串。
 Redis会根据当前值的类型和长度动态决定使用哪种内部编码实现。
 整型类型示例如下:
127.0.0.1:6379> set key 6379
OK
127.0.0.1:6379> object encoding key
"int"短字符串示例如下:
# ?于等于 39 个字节的字符串
127.0.0.1:6379> set key "hello"
OK
127.0.0.1:6379> object encoding key
"embstr"长字符串示例如下:
# ?于 39 个字节的字符串
127.0.0.1:6379> set key "one string greater than 39 bytes ........"
OK
127.0.0.1:6379> object encoding key
"raw"3.典型应用场景
缓存功能:
redis作为缓冲层,MySQL作为存储层,绝大部分的请求数据都是从redis中获取,由于redis支持高并发的特性,所以缓存能够起到加速读写降低后端压力的作用。
redis和MySQL组成的缓存存储结构

计数(Counter) 功能
 许多应用都会使用Redis作为计数的基础工具,它可以实现快速计数、查询缓存的功能,同时数
 据可以异步处理或者落地到其他数据源。如图2-11所示,例如视频网站的视频播放次数可以使用
 Redis来完成:用户每播放- -次视频,相应的视频播放数就会自增1。
 图2-11记录视频播放次数

共享会话(Session)
 如图2-12所示,一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自的服务器中,但这样会造成一个问题:出于负载均衡的考虑,分布式服务会将用户的访问请求均衡到不同的服务器上,并且通常无法保证用户每次请求都会被均衡到同一台服务器上,这样当用户刷新一
 次访问是可能会发现需要重新登录,这个问题是用户无法容忍的。
 图2-12 Session分散存储

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

手机验证码
 很多应用出于安全考虑,会在每次进行登录时,让用户输入手机号并且配合给手机发送验证码,然后让用户再次输入收到的验证码并进行验证,从而确定是否是用户本人。为了短信接口不会频繁访
 问,会限制用户每分钟获取验证码的频率,例如一分钟不能超过5次,如图2-14所示。
 图2-14短信验证码

此功能可以使用以下伪代码说明基本实现思路:
String 发送验证码(phoneNumber) {
    key = "shortMsg:limit:" + phoneNumber;
    // 设置过期时间为 1 分钟(60 秒)
    // 使? NX,只在不存在 key 时才能设置成功
    bool r = Redis 执?命令:set key 1 ex 60 nx
    if (r == false) {
        // 说明之前设置过该?机的验证码了
        long c = Redis 执?命令:incr key
        if (c > 5) {
            // 说明超过了?分钟 5 次的限制了
            // 限制发送
            return null;
        }
    }
    // 说明要么之前没有设置过?机的验证码;要么次数没有超过 5 次
    String validationCode = ?成随机的 6 位数的验证码();
    validationKey = "validation:" + phoneNumber;
    // 验证码 5 分钟(300 秒)内有效
    Redis 执?命令:set validationKey validationCode ex 300;
    // 返回验证码,随后通过?机短信发送给??
    return validationCode ;
}
// 验证用户输?的验证码是否正确
bool 验证验证码(phoneNumber, validationCode) {
    validationKey = "validation:" + phoneNumber;
    String value = Redis 执?命令:get validationKey;
    if (value == null) {
        // 说明没有这个?机的验证码记录,验证失败
        return false;
    }
    if (value == validationCode) {
        return true;
    } else {
        return false;
    }
}本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!