# redis-数据类型和发布订阅
[TOC]
## 一、redis数据类型
1.redis支持5种数据类型
```sh
String字符串
Hash哈希
List列表
Set集合
Sorted set有序集合
```
2.基础命令
```sh
set设置key
get 获取key的值
exists 判断key是否存在
keys显示所有的key
del删除指定的key
type 获取key的类型
```
更多详细命令见官方中文站点。redis.cn和redisdoc.com
## 二、数据类型命令和操作
### 1.字符串类型
1)操作命令
```sh
set设置key
get 获取key的值
mset同时设置多个key
mget同时获取抖个key
del删除指定的key
append追加内容到value
strlen获取字符串key的长度
incr自增key值
inryby指定步长的自增key
decr自减key值
decrby指定步长的自减key
incrbyfloat浮点类型的自增
```
2)简单举例:
```sh
10.0.0.41:6379> append luokey 123
(integer) 10#追加值到key中
10.0.0.41:6379> get luokey
"luogang123"
10.0.0.41:6379> incr abc
(integer) 1#自增
10.0.0.41:6379> incr abc
(integer) 2
10.0.0.41:6379> incrby abc 3
(integer) 7#步长为3的自增
10.0.0.41:6379> decr abc
(integer) 6 #自减
10.0.0.41:6379> decrby abc 2
(integer) 4#补偿为2的自减
10.0.0.41:6379> mset key1 a key2 b key3 c
OK#设置多个key
root@xxx ~]# 10.0.0.41:6379> mget key1 key2 key3
1) "a"#同时获取多个key
2) "b"
3) "c"
```
3)应用场景
常规计数:微博数,粉丝数等。
### 2.哈希类型命令(字典类型)
此类型的键最多232-1个,此类key中,可以存放多个数据,例如一本书的属性,颜色、价格、大小,可以存储在同一个哈希类型的key中,而不用分别存储在三个字符串类型的key中
1)命令
```sh
hset设置哈希key的一个字段的值
hget获取哈希key的一个字段的值
hmset设置一个哈希key的多个字段的值
hmget获取一个哈希key的多个字段的值
hgetall获取一个哈希key的所有字段的值
hdel删除一个哈希key的一个字段
del删除一个哈希key
```
2)简单举例:
```sh
11.10.0.0.41:6379> hset car name bmw
(integer) 1#设置key car的name字段的值
10.0.0.41:6379> hset car price 500
(integer) 1#设置key car的PRICE字段的值
10.0.0.41:6379> hmget car name price
1) "bmw"#查看哈希key car的多个字段的值
2) "500"
10.0.0.41:6379> hmset book name sguo price 100 color red
OK#设置哈希key name的多个字段
10.0.0.41:6379> hdel book name
(integer) 1#删除某个字段
10.0.0.41:6379> hgetall book
1) "price"#查看该key所有字段的值
2) "100"
3) "color"
4) "red"
3)应用场景
```
存储部分变更的数据,如用户信息等。
3.列表类型
用来存取一个有序的字符串的列表,可以分别从列表的两侧插入数据,也可以分别从列表两侧读取(弹出)数据。0表示第一个元素,-1表示最后一个元素,-2表示倒数第二个元素
1) 命令
```sh
lpush从列表左侧插入数据,可一次性插入多个元素
lpop从列表左侧弹出数据
rpush从列表右侧插入数据,可一次性插入多个元素
rpop从列表右侧弹出数据
lrange读取列表指定范围的数据
lrem从存于 key 的列表里移除前 count 次出现的值为 value 的元素
count > 0: 从头往尾移除值为 value 的元素。
count < 0: 从尾往头移除值为 value 的元素。
count = 0: 移除所有值为 value 的元素。
```
2)简单举例:
```sh
11.10.0.0.41:6379> lpush mylist k1 k2
(integer) 2#从左侧插入两个数据
10.0.0.41:6379> rpush mylist k3 k4
(integer) 4#从右侧插入两个数据
10.0.0.41:6379> lrange mylist 0 -1
1) "k2"#查看所有数据
2) "k1"
3) "k3"
4) "k4"
10.0.0.41:6379> lpop mylist
"k2"从左侧弹出数据
10.0.0.41:6379> lpop mylist
"k1"
10.0.0.41:6379> lpop mylist
"k3"
10.0.0.41:6379> lpop mylist
"k4"
10.0.0.41:6379> lpop mylist
(nil)#数据弹出完后,列表就为空
lrem mylist 0 k1
(integer) 1#移除列表中所有值为k1的元素
```
3)应用场景
消息队列系统,比如sina微博, 微信朋友圈
### 4.无序集合和有序集合
集合的概念就是定义一组数据,可以对这种类型的数据取交集、并集、差集等,合计分为无序合计和有序合计,差别是有序合集中的每个子,都有一个分数,可以根据分数排序或导出,无序集合命令已s开头,有序集合命令以z开头。
1)命令
```sh
sadd添加一个多多个元素到集合里
scard获取集合里面的元素数量
sinter获取两个集合的交集
sdiff获取两个集合的差集
sdiffstore获取两个集合的差集并写入新的集合中
smembers获取集合里面的所有key
```
2)举例
```sh
127.0.0.1:6379> sadd lxl pg1 pg2 baoqiang masu marong
(integer) 5
127.0.0.1:6379> sadd jnl baoqiang yufan baobeier zhouxingchi
(integer) 4
127.0.0.1:6379> SUNION lxl jnl
1) "zhouxingchi"
2) "baobeier"
3) "pg2"
4) "yufan"
5) "masu"
6) "baoqiang"
7) "pg1"
8) "marong"
127.0.0.1:6379> SINTER lxl jnl
1) "baoqiang"
127.0.0.1:6379> SDIFF lxl jnl
1) "masu"
2) "pg1"
3) "marong"
4) "pg2"
127.0.0.1:6379> SDIFF jnl lxl
1) "yufan"
2) "zhouxingchi"
3) "baobeier"
```
3)应用场景
微博中一个多个用户的共同好友等,排行榜中取top n等
## 三、发布订阅
redis也支持消息中间模式,即发布-订阅模式-MQ,redis的发布订阅功能较简单,这里做简单介绍,实际工作中,用的更多的mq是rabbitmq,kafka等其他消息中间件
使用消息中间件的好处是,发布者只管发布信息到指定通道,接受者只管从通道接受信息,不用管中间过程, 松耦合且易于扩展。
### 1.命令说明
```sh
PUBLISH channel msg
# 将信息 message 发送到指定的频道 channel
SUBSCRIBE channel [channel ...]
# 订阅频道,可以同时订阅多个频道
UNSUBSCRIBE [channel ...]
# 取消订阅指定的频道, 如果不指定频道,则会取消订阅所有频道
PSUBSCRIBE pattern [pattern ...]
# 订阅一个或多个符合给定模式的频道,每个模式以 * 作为匹配符,比如 it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 开头的频道( news.it 、 news.global.today 等等),诸如此类
PUNSUBSCRIBE [pattern [pattern ...]]
# 退订指定的规则, 如果没有参数则会退订所有规则
PUBSUB subcommand [argument [argument ...]]
# 查看订阅与发布系统状态
```
注意:使用发布订阅模式实现的消息队列,当有客户端订阅channel后只能收到后续发布到该频道的消息,之前发送的不会缓存,必须Provider和Consumer同时在线。
### 2.发布订阅例子
同时打开两个redis窗口,然后一个从库发布频道,另一个窗口订阅频道
1)订阅单个频道
```sh
# 窗口1:
127.0.0.1:6379> SUBSCRIBE baodi
# 窗口2:
127.0.0.1:6379> PUBLISH baodi "jin tian zhen kaixin!"
```
订阅成功后,第一个窗口输入的消息,会在第二个窗口显示
2)订阅多频道:
```sh
# 窗口1:
127.0.0.1:6379> PSUBSCRIBE wang*
# 窗口2:
127.0.0.1:6379> PUBLISH wangbaoqiang "jintian zhennanshou "
```