## 一、Redis简介
概念:Redis (REmote DlctionaryServer)是用C语言开发的一个开源的高性能犍
值对(key-value)数据库。
特征:
- 1.数据问没有必然的关联关系
- 2.内部采用单线程机制进行工作
- 3.高性能。官方提供测试数据,50个并发执行100000个请求,读的速度110000次/s,写的速度是81000次/s。
- 4.多数据类型支持
- 字符串类型 string
- 列表类型 list
- 散列类型 hash
- 集合类型 set
- 有序集合类型 sorted_set
- 5.持久化支持。可以进行数据灾难恢复。
## 二、Redis的应用
- 为热点数据加速查询。如热点商品、热点新闻、热点资讯、推广类等高访问量信息等。
- 队列任务。如秒杀、抢购、购票排队等。
- 即时信息查询,如各种排行榜、网站访问统计、公交到站信息、在线人数信息、设备信号等
- 消息队列
- 分布式锁
## 三、Redis的基本操作
### 1、信息添加
- 功能:设置key,value数据
- 命令:
```bash
set key value
```
- 实例:
```bash
set name respon
```
### 2、 信息查询
- 功能:根据key查询对应的value,如果不存在就返回空(nil)
- 命令:
```bash
get key
```
- 实例:
```bash
get name
```
### 3、help命令
- 输入help命令就可以查看help内容
```bash
127.0.0.1:6379> help
redis-cli 5.0.9 (git:9414ab9b)
To get help about Redis commands type:
"help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
```
### 4、 退出客户端方式
- 功能:退出客户端
- 命令
```bash
quit
exit
<ESC> : 不建议使用
```
## 四、Redis的数据存储类型
redis的数据存储格式:
- redis自身就是一个Map,其中所有的数据都是采用key:value的形式存储;
- 数据类型指的是存储的数据的类型,也就是value部分的类型,key部分永远都是字符串

### 1、string
存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型;
存储数据的格式:一个存储空间保存一个数据;
存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用,但他本质上还是字符串。

- 基本操作
- 添加/修改单个数据
```bash
set key value
```
- 获取单个数据
```bash
get key
```
- 删除数据
```bash
del key
```
- 添加/删除多个数据
```bash
mset key1 value1 key2 value2 ...
```
- 获取多个数据
```bash
mget key1 key2 ...
```
- 获取数据字符个数(字符串长度)
```bash
strlen key
```
- 追加新信息至原始信息后部(如果原始信息存在则追加,不存在则新建)
```bash
append key value
```
- **扩展操作1:数值增减操作**
- 设置数值数据增加指定范围的值
```shell
incr key #给数值数据key执行+1操作
incr key incrementsh #给数值数据key执行+increment操作
incrbyfloat key increment #给数值数据key执行+increment操作,这个increment可以为小数
```
- 设置数值数据减少指定范围的值
```bash
decr key #给数值数据key执行-1操作
decrby key decrement #给数值数据key执行-decrement操作
```
- 应用场景:由于string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。redis所有的操作都是原子性的,采用单线程处理所有业多,命令是一个一个执行的,因此无需考虑并发带来的数据影响。在这种情况下redis可以为数据库中数据表分表提供一个可靠的id增长策略。
**注**:如果操作的key不是数值数据或数值超出允许范围时,就会出现错误:
```shell
(error) ERR value is not an integer or out of range
```
- **扩展操作2:数据时效性设置**
- 设置数据具有指定的生命周期
```shell
setex key seconds value #设置key的置为value,生命周期为seconds(秒)。例如 setex tel 10 18846447035
psetex key milliseconds value #设置key为value,生命周期为milliseconds(毫秒)。例如 setex tel 10 18846447035
```
- 应用场景:单个号码一天只能投一次票
- **string 类型数据操作的注意事项**
数据操作不成功的反馈与数据正常操作之间的差异
- 表示运行结果是否成功
(integer)0 →false失败
(integer) 1 →true成功
- 表示运行结果值
(integer)3 →3 3个
(integer)1 →1 1个
- 数据未获取到
(nil)等同于null
- 数据最大存储量
512MB
- 数值计算最大范围(java中的long的最大值)
9223372036854775807
- **string类型应用场景**
- 微博主页粉丝数量和关注用户数量
在redis中为大V用户设定用户信息,以用户主见和属性值作为key,后台设定定时刷新策略即可
```bash
set user:id:3506728370:fans 11122222 #设置id为3506728370的用户的粉丝数量为11122222
```
还可以在redis中设置json数据存储用数据
```bash
set user:id:3506728370 {id:3506728370,name:miantiao,fans:11122222}
```
- **string 中的key设置约定**
数据库中的热点数据key命名惯例
表名 : 主键名 : 主键值 :字段名
order : id : 29437595 : name
### 2、hash
在redis中,string对象类数据的存储如果具有较频繁的更新需求操作会显得笨重,比如下面的数据,想要是对fans数量更新时,操作起来就不方便了,但是如果将值按照第张示意图存放时,更新起来就方便多了。
- **hash数据类型:**
- 新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息;
- 需要的存储结构:一个存储空间保存多个键值对数据;
- hash类型:底层使用hash表结构实现数据存储。

- **基本操作**
- 添加/修改数据
```bash
hset key field value
```
- 获取数据
```bash
hget key field #获取指定field的value
hgetall key #获取全部fields和value
```
- 删除数据
```bash
hdel key field1 [field2 ...]
```
- 添加/修改多个数据
```bash
hmset key field1 value1 field2 value2 ...
```
- 获取多个数据
```bash
hmget key field1 field2 ...
```
- 获取哈希表中字段的数量
```bash
hlen key
```
- 获取哈希表中是否存在指定的字段
```bash
hexists key field
```
- **扩展操作**
- 获取哈希表中所有的key和所有的value
```bash
hkeys key #获取所有的键
hvals key #获取所有的值
```
- 设置指定字段的数值数据增加指定范围的值
```bash
hincrby key field increment
hincrbyfloat key field increment
```
- **注意事项**
- hash类型下的value智能存储字符串,不允许存储其他数据类型,不存在嵌套现象,如果未获取到,那么对应的值为(nil);
- 每个hash可以存储2^23^-1个键值对;
- hash 类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象的属性。但hash设计初衷不是为了存储大量对象而设计的切记不可滥用,更不可以将hash作为对象列表使用。
- **应用场景:商场购物车**
解决方案
以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息将商品编号作为field,购买数量作为value进行存储
添加商品:追加全新的field与value
浏览:遍历hash
更改数量:自增/自减,设置value值删除商品:删除field
清空: 删除key
```bash
hsetnx key field value # 如果存在field,则不作更改,如果不存在则创建field
```
- **应用场景:抢购商品**
以商家id作为key
将参与抢购的商品id作为field
将参与抢购的商品数量作为对应的value抢购时使用降值的方式控制产品数量
实际业务中还有超卖等实际问题,这里不做讨论
### 3、list
- **list数据类型**
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
需要的存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序
list类型:保存多个数据,底层使用双向链表存储结构实现

- **基本操作**
- 添加/修改数据
```bash
lpush key value1 [value2] ...
rpush key value1 [value2] ...
```
- 获取数据
```bash
lrange key start stop
lindex key index
llen key
```
- 说去并移除数据
```bash
lpop key
rpop key
```
- **扩展操作:list阻塞数据获取**
- 规定时间内获取并移除数据
```bash
blpop key [key ...] timeout #取值,key内有值就取出,没值就等待timeout,超时退出
```
- **扩展操作:移除指定位置数据**
- 移除指定数据:
```bash
lrem key count value #从左侧开始移除key中count个value。例如lrem list0 2 b
```
- **注意事项:**
- list中保存的数据都是string类型的,数据总容量是有限的,最多2^32^-1个元素(4294967295)。
- list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作
- 获取全部数据操作结束索引设置为-1
- list可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
- **应用场景:按照时间顺序展示最新消息**
- 依赖list的数据具有顺序的特征对信息进行管理
- 使用队列模型解决多路信息汇总合并的问题
- 使用栈模型解决最新消息的问题
### 4、set
- **set数据类型**
- 新的存储需求:存储大量的数据,在查询方面提供更高的效率
- 需要的存储结构:能够保存大量的数据,高效的内部存储机制,便于查询
- set类型:与hash存储结构完全相同,仅存储键,不存储值 (nil),并且值是不允许重复的

- **基本操作**
- 添加数据
```bash
sadd key member1 [member2 ...]
```
- 获取全部数据
```bash
smembers key
```
- 删除数据
```bash
srem key member1 [member2 ...]
```
- 获取集合数据总量
```bash
scard key
```
- 判断集合中是否包含指定数据
```bash
sismember key member
```
- **扩展操作:随机获取数据**
- 随机获取集合中指定数量的数据
```
srandmember key [count]
```
- 随机获取集合中的某个数据并将该数据移除集合
```bash
spop key [count]
```
- **扩展操作:多个集合操作**
- 求两个集合的交、并、差
```bash
sinter key1 [key2 ...]
sunion key1 [key2 ...]
sdiff key1 [key2 ...]
```
- 求两个集合的交、并、差并存储到指定集合中
```bash
sinterstore destination key1 [key2 ...]
sunionstore destination key1 [key2 ...]
sdiffstore destination key1 [key2 ...]
```
- 将指定数据存原始集合中移动到目标集合中
```bash
smove source destination member
```
Tips:redis应用于同类信息的关联搜索,二度关联搜索,深度关联搜索显示共同关注(一度)、显示共同好友(一度)、由用户A出发,获取到好友用户B的好友信息列表(一度)由用户A出发,获取到好友用户B的购物清单列表(二度)由用户A出发,获取到好友用户B的游戏充值列表(二度);
- **注意:**
- set类型不允许数据重复,如果添加的数据在set中已经存在,将只保留一份;
- set虽然与hash的存储结构相同,但是无法启用hash中存储值的空间;
- **应用场景:用户的不同角色权限合并**
- **应用场景:网址站访问量统计**
- **应用场景:访问黑名单**
### 5、sorted_set
- **sorted_set数据类型**
- 新的存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式
- 需要的存储结构:新的存储模型,可以保存可排序的数据
- sorted_set类型:在set的存储结构基础上添加可排序字段

- **基本操作**
- 添加数据
```bash
zadd key score1 member1 [score2 member2 ...]
```
- 获取全部数据
```bash
zrange key start stop [WITHSCORES] #升序排序 [withscores]:表示在显示结果时携带排序用的数值
zrevrange key start stop [WITHSCORES] #降序排序
```
- 删除数据
```bash
zrem key member [member ...]
```
- 按条件获取数据
```bash
zrangebyscore key min max [WITHSCORES] [LIMIT offset count] #查询key中大于min小于max的值,[withscores]:表示在显示结果时携带排序用的数值,[limit]:对结果集进行限制,limit 0 3 表示只输出结果集从索引0开始的3个值
zrevrangebyscore key min max [WITHSCORES]
```
- 按条件删除数据
```bash
zremrangebyrank key start stop #按照索引删除,start表示开始索引,stop表示结束索引
zremrangebyscore key min max #按值删除
```
- 获取聚合数据总量
```bash
zcard key
zcount key min max
```
- 集合交、并操作
```bash
zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
# 求交集,numkey:用于求交集的集合个数,WEIGHTS:每个集合的权重 AGGREGATE:交集结果中的值为所有值得和sum、最小值min、最大值max
zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
#求并集
```
- **扩展操作**
- 获取数据对应的索引(排名)
```bash
zrank key member #升序名次,即索引
zrevramk key member #降序名次
```
- score值获取与修改
```bash
zscore key member #获取key的member的score
zincrby key increment member #给key的member的score增加increment
```
- **注意事项**
- score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992
- score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时候要慎重
- sorted_set底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果
- **应用场景**
- 应用于定时任务执行顺序管理,比如vip到期时间提醒
- 带有权重的任务执行顺序管理

Redis学习笔记(一)