关系型数据的ACID特性:事务的四大特性:原子性,一致性,隔离性,持久性
关系型数据库应对的三高问题:高并发,高效率,高扩展
关系型数据库和非关系型数据库
关系型数据库的数据存储在表中,无法应对陡增的数据
非关系型数据库使用键值对的方式进行存储数据:redis可以用作缓存
redis概述
直接操作内存中的数据
优势:
开源的,分布式,水平可扩展的
对数据高并发读写
单线程操作
缺点:
事务处理非常简单
不能做复杂的关系数据库模型
各种命令及使用场景
使用命令**“redis-cli”**进入redis服务器
redis的类型和map相似
常见的五大类型:String ,hash,list,set,zset
各种返回结果的表示什么
nil和java中的null一样
1 操作成功
0 操作失败
-1 示永久存在
-2 表示已经超时
其他时间 表示存活的时间
String类型
应用场景
1.计数器
2.共享session,对某个用户的身份进行校验
命令格式 | 功能 | 案例 |
---|---|---|
set key value | 将key-value缓存redis中 | set name dafei |
get key | 从redis中获取key对应value值 | get name |
incr key | 将key对应value值 + 1,只能事先将字段设置为数值 | incr age |
decr key | 将key对应value值-1 | decr age |
setex key seconds value | 将key-value缓存到redis中,seconds 秒后失效 | setex sex 10 man |
ttl key | 查看key存活时间 | ttl sex |
del key | 从redis中删除key | del name |
setnx key value | 如果key已经存,不做任何操作,如果key不存,直接添加 | setnx name xiaofei |
incr value 只能对数值进行增加
hash类型
应用场景
1.存储对象,登录用户信息
类似map中的map
命令格式 | 功能 | 案例 |
---|---|---|
hset key field value | 将field value对缓存到redis中hash中,键值为key | hset user name dafei |
hget key field | 从key对应hash列表中获取field字段 | hget user name |
hexists key field | 判断key对应的hash列表是否存在 field字段 | hexists user age |
hdel key field | 删除key对应hash列表中field字段 | hdel user age |
hincrby key field increment | 给key对应hash列表中field字段 + increment | hincrby user age 10 |
hlen key | 查看key对应的hash列表field的数量 | hlen user |
hkeys key | 获取key对应的hash列表所有的field值 | hkeys user |
hvals key | 获取key对应的hash列表所有的field对应的value值 | hvals user |
hgetall key | 获取key对应的hash列表中所有的field及其对应的value值 | hgetall user |
list类型
结构就像双向链表,操作头尾的数据,允许重复
使用场景
用户收藏列表
命令格式 | 功能 | 案例 |
---|---|---|
rpush key value | 从右边往key集合中添加value值 | rpush hobby java |
lrange key start stop | 从左边开始列表key集合,从start位置开始,stop位置结束,0 -1表示取所有 | lrange hobby 0 -1 |
lpush key value | 从左边往key集合中添加value值 | lpush hobby c++ |
lpop key | 弹出key集合中最左边的数据 | lpop hobby |
rpop key | 弹出key集合中最右边的数据 | rpop hobby |
llen key | 获取列表长度 | llen hooby |
set类型
无序的,不允许重复
使用场景
1.去重
2.抽奖功能
命令格式 | 功能 | 案例 |
---|---|---|
sadd key members | 向key集合中添加member元素 | sadd myset a b c |
smembers key | L列出key集合中的所有元素 | smembers myset |
srem key member | 删除key集合中的某一个元素 | srem myset b |
spop key count | 从key集合中随机弹出count个集合 | spop myset 2 |
Sorted set(zset)类型
应用场景
具有排序的功能:将排名的名字作为score
命令格式 | 功能 | 示例 |
---|---|---|
zadd key score member | 向key集合中添加member元素,分数为score | zadd play 10 a |
zincrby key count member | 向key集合中的member元素 数值增加count | zincrby play 100 a |
zrange key start stop withscore | 列出开始到结束范围的元素,升序排列显示分数 | zrange play 0 -1 withscore |
zrevrange key start stop withscore | 列出开始到结束范围的元素,降序排列显示分数 | zrevrange play 0 -1 withscore |
zrank key member | 返回元素\正序排名的位置 | zrank play b |
zrevrank key member | 返回元素倒叙排名的位置 | zrevrank play b |
zcard key | 返回集合中元素的个数 | zcard play |
各个类型的使用场景
1.用来存储对象还是字符串
对象使用hash,字符串使用list,set,string zset
2.是否有序,可重复
有序可重复使用list,无序不可重复使用set,zset
3.是否进行排序
不需要排序使用set,需要排序使用zset
value设计
需要排序的就使用zset,
剩下的就使用string,java操作方便,减少泛型的操作,将所有的value都转化为json
key设计
保证唯一性(将id写在名字中)
user_token:1:{ }
可读性(做到见名知意,一般使用:进行分割)
employee_info:id1
灵活性
时效性
key一定要设置过期时间,否则数量多了容易造成宕机
redis全局命令
命令格式 | 功能 | 示例 |
---|---|---|
keys * | 列出所有的key | keys * |
exists key | 判断这个key是否存在 | exists name |
expire key time | 给key设置存活时间 | expire user 20 |
persist key | 取消存活时间 | presist user |
redis安全性
给redis加密码
修改密码后需要重启服务
若出现服务不能连接的情况就可能是没有启动服务器
在Java中使用redis
1.使用jedis
①添加jedis配置文件application.yaml
②在java实体类中使用@ConfigurationProperties(prefix = “jedis.pool”)加载配置文件
③需要编写jedis配置类,添加@Configuration注解,获取连接池
④使用的方式,需要关闭资源
2.使用lettuce
使用的方法很简单
①导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-Redis</artifactId>
</dependency>
②配置redis
spring:
Redis:
host: 127.0.0.1
port: 6379
password: admin
③使用方式
// 操作string
//template.opsForValue().xx();
// 操作hash
//template.opsForHash().xx();
// 操作list
//template.opsForList().xx();
// 操作set
//template.opsForSet().xx();
// 操作zset
//template.opsForZSet().xx();
//spring-data-Redis 方法是Redis 命令全称
//template.opsForList().rightPush() //rpush
//全局命令在template类上
//template.keys("*");
事务执行的三个阶段
事务开始到执行经历的三个阶段
1.开始事务,使用multi开始
2.命令入队
3.执行事务,使用exec执行
将多条命名存起来,再统一执行
不会关心是否全部成功或者全部失败,即使中间有一条命令执行错误后面的命令也会继续执行
即redis的事务是不具有原子性的
redis持久化操作
为什么重启服务后,会出现有的数据会丢失,有的不会丢失
原因:redis会不定时将数据持久化到磁盘中
redis的3种持久化方式:
1.快照方式(RDB),
将数据转成二进制文件持久化到磁盘中
触发方式
手动触发:save命令,数据多了容易阻塞, ;bgsave命令,redis使用fork创建子进程实现RDB持久化
自动触发:使用命令 save m n ,在m秒内有n次操作就会自动触发bgsave命令
优点:
1.紧凑压缩的二进制文件,用于文件备份,全量复制场景
2.redis使用RDB恢复数据的方式远远快于AOF
**缺点:**数据会丢失,不能做到数据秒级持久化,版本不同有兼容问题
2.文件追加方式(AOF)
追加是命令,将命令写到文件中去,能做到持久化的实时性
redis默认不开启,在配置文件中进行开启, appendonly yes
优点:
1.数据安全性高
2.不下心使用了删除命令后可以进行数据的恢复
3.AOF太大的时候后台会自动重写AOF
4.AOF日志的存在不用担心设备断电的情况
缺点:
AOF的体积比RDB更大
AOF持久化的速度比RDB更慢
3.RDB和AOF混合使用
AOF
**缺点:**数据会丢失,不能做到数据秒级持久化,版本不同有兼容问题
2.文件追加方式(AOF)
追加是命令,将命令写到文件中去,能做到持久化的实时性
redis默认不开启,在配置文件中进行开启, appendonly yes
优点:
1.数据安全性高
2.不下心使用了删除命令后可以进行数据的恢复
3.AOF太大的时候后台会自动重写AOF
4.AOF日志的存在不用担心设备断电的情况
缺点:
AOF的体积比RDB更大
AOF持久化的速度比RDB更慢
3.RDB和AOF混合使用
结合了两者的优点,现将当前数据一RDB的形式写在文件开头,后续的操作使用AOF的格式存入文件