3.1 字符串
在 Redis 中,字符串可以存储以下三种类型的值:
- 字节串(byte string)
- 整数
- 浮点数
HINT:浮点数的取值范围与精度和 IEEE 754 标准的双精度浮点数 double 相同。
3.1.1 Redis 字符串自增和自减的命令
当用户将一个值存储到 Redis 字符串中,如果该值可以被解释为十进制整数或浮点数,那么 Redis 会察觉到,并且允许用户对该字符串执行自增或者自减操作。
3.1.2 处理 Redis 字符串子串和二进制位的命令
HINT:注意,Redis 在解释二进制串的时候是按照偏移量从高到低(从左往右,从 0 开始)来的:
127.0.0.1:6379> setbit another-key 2 1
(integer) 0
127.0.0.1:6379> setbit another-key 7 1
(integer) 0
127.0.0.1:6379> get another-key
"!"
这里经过两行的setbit
后,生成二进制位串是0010 0001
,是从左往右的而且是从 0 开始的。
3.2 列表
Redis 的列表允许从序列的两端推入或弹出元素、获取列表元素、以及执行各种常见的列表操作。
3.2.1 常用的列表命令
127.0.0.1:6379> rpush list-key last
(integer) 1
127.0.0.1:6379> lpush list-key first
(integer) 2
127.0.0.1:6379> rpush list-key 'new last'
(integer) 3
127.0.0.1:6379> lrange list-key 0 -1
1) "first"
2) "last"
3) "new last"
127.0.0.1:6379> lpop list-key
"first"
127.0.0.1:6379> lpop list-key
"last"
127.0.0.1:6379> lrange list-key 0 -1
1) "new last"
127.0.0.1:6379> rpush list-key a b c
(integer) 4
127.0.0.1:6379> lrange list-key 0 -1
1) "new last"
2) "a"
3) "b"
4) "c"
127.0.0.1:6379> ltrim list-key 2 -1
OK
127.0.0.1:6379> lrange list-key 0 -1
1) "b"
2) "c"
3.2.2 阻塞式列表弹出、在列表之间移动元素的命令
以下几个列表命令可以将元素从一个列表移动到另一个列表,或者阻塞执行命令的客户端直到有其他客户端给列表添加元素为止:
127.0.0.1:6379> rpush list item1
(integer) 1
127.0.0.1:6379> rpush list item2
(integer) 2
127.0.0.1:6379> rpush list2 item3
(integer) 1
127.0.0.1:6379> brpoplpush list2 list 1
"item3"
127.0.0.1:6379> brpoplpush list2 list 1
(nil)
(1.00s)
127.0.0.1:6379> lrange list 0 -1
1) "item3"
2) "item1"
3) "item2"
127.0.0.1:6379> brpoplpush list list2 1
"item2"
127.0.0.1:6379> blpop list list2 1
1) "list"
2) "item3"
127.0.0.1:6379> lrange list 0 -1
1) "item1"
127.0.0.1:6379> blpop list list2 1
1) "list"
2) "item1"
127.0.0.1:6379> blpop list list2 1
1) "list2"
2) "item2"
127.0.0.1:6379> blpop list list2 1
(nil)
(1.01s)
3.3 集合
Redis 的集合以无序方式来存储多个各不相同的元素,可以快速对集合执行增删查。
3.3.1 常用集合命令
127.0.0.1:6379> sadd set-key a b c
(integer) 3
127.0.0.1:6379> srem set-key c d
(integer) 1
127.0.0.1:6379> srem set-key c d
(integer) 0
127.0.0.1:6379> scard set-key
(integer) 2
127.0.0.1:6379> smembers set-key
1) "a"
2) "b"
127.0.0.1:6379> smove set-key set-key2 a
(integer) 1
127.0.0.1:6379> smove set-key set-key2 c
(integer) 0
127.0.0.1:6379> smembers set-key
1) "b"
127.0.0.1:6379> smembers set-key2
1) "a"
3.3.2 组合和处理第一份集合的 Redis 命令
集合更好的使用方式为组合和关联多个集合:
127.0.0.1:6379> sadd skey1 a b c d
(integer) 4
127.0.0.1:6379> sadd skey2 c d e f
(integer) 4
127.0.0.1:6379> sdiff skey1 skey2
1) "a"
2) "b"
127.0.0.1:6379> sdiff skey2 skey1
1) "e"
2) "f"
127.0.0.1:6379> sinter skey1 skey2
1) "c"
2) "d"
127.0.0.1:6379> sunion skey1 skey2
1) "a"
2) "e"
3) "f"
4) "c"
5) "d"
6) "b"
3.4 散列
Redis 散列可以将多个键值对存储到一个 Redis 键中。
3.4.1 添加和删除键值对的散列操作
HSET 和 HGET 只能处理一个键值对,而 HMSET 和 HMGET 可以获得多个。
127.0.0.1:6379> hmset hash-key k1 v1 k2 v2 k3 v3
OK
127.0.0.1:6379> hmget hash-key k2 k3
1) "v2"
2) "v3"
127.0.0.1:6379> hlen hash-key
(integer) 3
127.0.0.1:6379> hdel hash-key k1 k3
(integer) 2
127.0.0.1:6379> hlen hash-key
(integer) 1
3.4.2 散列的批量操作命令
127.0.0.1:6379> hmset hash-key2 short hello long 1000*'1'
OK
127.0.0.1:6379> hkeys hash-key2
1) "short"
2) "long"
127.0.0.1:6379> hvals hash-key2
1) "hello"
2) "1000*1"
127.0.0.1:6379> hexists hash-key2 num
(integer) 0
127.0.0.1:6379> hincrby hash-key2 num 1
(integer) 1
127.0.0.1:6379> hexists hash-key2 num
(integer) 1
HINT:hincrby
指令对散列中一个尚未存在的键执行自增操作时,会将键的值当做 0 来处理,并且会添加进散列中。
3.5 有序集合
有序集合存储成员与分值之间的映射,并且提供分值处理命令,以及根据分值大小有序获取或扫描成员和分值的命令。
3.5.1 常用的有序集合命令
127.0.0.1:6379> zadd zset-key a 3 b 2 c 1
(error) ERR value is not a valid float
127.0.0.1:6379> zadd zset-key 3 a 2 b 1 c
(integer) 3
127.0.0.1:6379> zcard zset-key
(integer) 3
127.0.0.1:6379> zincrby zset-key c 3
(error) ERR value is not a valid float
127.0.0.1:6379> zincrby zset-key 3 c
"4"
127.0.0.1:6379> zscore zset-key b
"2"
127.0.0.1:6379> zrank zset-key c
(integer) 2
127.0.0.1:6379> zcount zset-key 0 3
(integer) 2
127.0.0.1:6379> zrem zset-key b
(integer) 1
127.0.0.1:6379> zrange zset-key 0 -1 withscores
1) "a"
2) "3"
3) "c"
4) "4"
HINT:有序集合的ZADD
和ZINCRBY
指令都是分值在前,成员在后。
3.5.2 有序集合范围指令和并集交集
127.0.0.1:6379> zadd zset-1 1 a 2 b 3 c
(integer) 3
127.0.0.1:6379> zadd zset-2 4 b 1 c 0 d
(integer) 3
127.0.0.1:6379> zinterstore zset-i 2 zset-1 zset-2
(integer) 2
127.0.0.1:6379> zrange zset-i 0 -1 withscores
1) "c"
2) "4"
3) "b"
4) "6"
127.0.0.1:6379> zunionstore zset-u 2 zset-1 zset-2 aggregate min
(integer) 4
127.0.0.1:6379> zrange zset-u 0 -1 withscores
1) "d"
2) "0"
3) "a"
4) "1"
5) "c"
6) "1"
7) "b"
8) "2"
127.0.0.1:6379> zunionstore zset-u2 3 zset-1 zset-2 set-1
(integer) 4
127.0.0.1:6379> zrange zset-u2 0 -1 withscores
1) "d"
2) "0"
3) "a"
4) "1"
5) "c"
6) "4"
7) "b"
8) "6"
HINT:可以在执行ZINTERSTORE
和ZUNIONSTORE
(并集交集)运算时传入不同的聚合函数,如:min、max、sum三个中的一个。默认使用的是 sum。
3.6 发布和订阅
发布与订阅的特点是订阅者负责订阅频道,发送者负责向频道发送二进制字符串消息。每当有消息被发送到指定频道后,该频道的所有订阅者都会收到消息。
发布与订阅的指令:
还挺有意思的,有点像小聊天室。
但是**订阅/发布**
也有弊端:
- Redis系统稳定性:对于旧版 Redis,如果一个订阅了某频道的客户端读取消息的速度不够快的话,不断积压的消息会使得 Redis 输出缓冲区的体积越来越大,导致 Redis 的速度放慢、崩溃。新版 Redis 则不会,因为会自动断开不符合
client-output-buffer-limit pubsub
配置选项要求的订阅客户端。 - 数据传输的可靠性:如果客户端在执行订阅操作的过程中断线,那么客户端将丢失在断线期间发送的所有消息。
3.7 其他命令
3.7.1 排序
SORT
命令默认升序。可以处理列表、集合、有序集合三种数据类型。
使用SORT
命令可以实现以下功能:
- 指定字符排序规则,如将默认的升序改为降序;
- 将元素看作为数字或二进制字符串来排序;
- 使用被拍许愿树之外的其他值作为权重来排序。
127.0.0.1:6379> rpush sort-input 23 15 110 7
(integer) 4
127.0.0.1:6379> sort sort-input
1) "7"
2) "15"
3) "23"
4) "110"
127.0.0.1:6379> lrange sort-input 0 -1
1) "23"
2) "15"
3) "110"
4) "7"
127.0.0.1:6379> 不会影响原来的结果 只会返回排序好的内容给你看
127.0.0.1:6379> sort sort-input alpha
1) "110"
2) "15"
3) "23"
4) "7"
127.0.0.1:6379> hset d-7 field 5
(integer) 1
127.0.0.1:6379> hset d-15 field 1
(integer) 1
127.0.0.1:6379> hset d-23 field 9
(integer) 1
127.0.0.1:6379> hset d-110 field 3
(integer) 1
127.0.0.1:6379> sort sort-input by d-*->field
1) "15"
2) "110"
3) "7"
4) "23"
#获取外部数据,并将它们用作命令的返回值,而不是返回被排序的数据
127.0.0.1:6379> sort sort-input by d-*->field get d-*->field
1) "1"
2) "3"
3) "5"
4) "9"
127.0.0.1:6379> lrange sort-input 0 -1
1) "23"
2) "15"
3) "110"
4) "7"
3.7.2 基本的 Redis 事务
Redis 有五个可以让用户在不被打断的情况下对多个键执行操作:WATCH
、MULTI
、EXEC
和UNWATCH
。
Redis 的基本事务需要用到**MULTI**
、**EXEC**
命令,这种事务可以让一个客户端在不被其他客户端打断的情况下执行多个命令。被**MULTI**
、**EXEC**
包围的所有命令会一个接一个执行直到全部执行完。当一个事务执行完毕后,Redis 才会处理其他客户端的命令。
HINT:Redis 要在接收到EXEC
命令后才会执行那些位于MULTI
和EXEC
之间命令的入队操作。而且,在这两条指令间如果输入了错误指令,会导致键入**EXEC**
之后事务被丢弃。
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> hset value 1
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379(TX)> hset 1 value
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379(TX)> hset set-key value 1
QUEUED
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> hset set-key value 1
QUEUED
127.0.0.1:6379(TX)> EXEC
1) (integer) 1
3.7.3 键的过期时间
可以使用**DEL**
命令显式删除无用数据,也可以通过 Redis 的过期时间特性让一个键在给定的时限之后自动被删除。