🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 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 " ```