一、NoSQL 和 SQL 区别
二、认识 Redis
🍀 Redis 诞生于2009年,全称是 Remote Dictionary Server,远程字典服务器,是一个基于 内存的键值型 NoSQL 数据库
🍀 键值(key-value)型,value 支持多种不同数据结构,功能丰富
🍀 单线程,每个命令具备原子性
🍀 低延迟,速度快(基于内存、IO 多路复用、良好的编码)
🍀支持数据持久化
🍀 支持主从集群、分片集群
🍀支持多语言客户端
三、Redis 的数据结构介绍
🍀 Redis 是一种 key-value 类型的数据库
🍀 key 一般是 String 类型
🍀 value 的类型多种多样(如下图所示)
Redis 命令官网: https://redis.io/commands
四、Redis 通用命令
🍀 通用命令是不分数据类型的,各种数据类型都可以使用的命令
🌼 KEYS
:查看符合模板的所有 key
🌼 DEL
:删除一个指定的 key
🌼 EXISTS
:判断 key 是否存在
🌼 EXPIRE
:给一个 key 设置有效期(过期时间)有效期到期时该 key 会被自动删除
🌼 TTL
:查看一个 key 的剩余有效时间
- -1:永不过期
- -2:已经过期
可通过
help [command]
命令查看某个命令的具体用法
五、String 类型
🍃 String 类型(字符串类型)是 Redis 中最简单的存储类型
🍃 value 是字符串
🍃 根据字符串的格式不同,可分为 3 类(String、int、float)
① String:普通字符串
② int:整数类型(可做自增、自减操作)
③ float:浮点类型(可做自增、自减操作)
🍃 不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同
🍃 字符串类型的最大空间不能超过 512M
常见命令有:
🌺 SET
:添加或修改(如果键值对已存在的话)一个 String 类型的键值对
🌺 GET
:根据 key 获取 String 类型的 value
🌺 MSET
:批量添加多个 String 类型的键值对
🌺 MGET
:根据多个 key 获取多个 String 类型的 value
🌺 INCR
:让一个整型的 key 自增 1
🌺 INCRBY
:让一个整型的 key 自增指定步长 incrby num 2 【让 num 值自增 2】
🌺 INCRBYFLOAT
:让一个浮点类型的数字自增指定步长
🌺 SETNX
:添加一个 String 类型的键值对,前提是这个 key 不存在,否则不执行【添加】
🌺 SETEX
:添加一个 String 类型的键值对,并且指定有效期
六、key 的格式
🌱 Redis 的 key 允许用多个单词形成层级结构
🌱 多个单词之间用【:
】分隔
🌱 该格式并非固定,可根据自己的需求删除或添加词条
例如项目名称叫【crm】,有 user 和 product 两种不同类型的数据。则可以如下所示定义 key:
① user 相关的 key:
crm:user:1
② product 相关的 key:
crm:product:1
🌱 如果 Value 是一个 Java 对象。例如一个 User 对象,则可以将对象序列化为 JSON 字符串后存储:
七、Hash(散列)类型
💚 Hash 类型(也叫散列)
💚 value 是一个无序字典 【类似 Java 中的 HashMap
】
💚 Hash 类型可以将对象中的每个字段独立存储,可针对单个字段做增删改查
Hash 的常见命令有:
🌱HSET key field value
:添加或修改 Hash 类型 key 的 field 的值
🌱HGET key field
:获取一个 Hash 类型 key 的 field 的值
🌱HMSET
:批量添加多个 Hash
类型 key
的 field
的值
🌱HMGET
:批量获取多个 Hash
类型key
的 field
的值
🌱HGETALL
:获取一个 Hash
类型的key
中的所有的 field
和 value
🌱HKEYS
:获取一个 Hash
类型的key
中的所有的 field
🌱HVALS
:获取一个 Hash
类型的key
中的所有的 value
🌱HINCRBY
: 让一个 Hash
类型key
的字段值(field)自增并指定步长
🌱HSETNX
:添加一个 Hash
类型的key
的 field
值,前提是这个 field 不存在,否则不执行
八、List 类型
🌼 Redis 中的 List 类型与 Java 中的 LinkedList 类似
🌼 可看做是一个双向链表结构(既可以支持正向检索和反向检索)
🌼 特点:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
🌼 常用来存储有序数据(如:朋友圈点赞列表,评论列表)
🍃 LPUSH key element ...
:向列表左侧插入一个或多个元素
🍃 LPOP key count
:移除并返回列表左侧的第一个元素,没有则返回 nil(count:取的个数)
🍃 RPUSH key element ...
:向列表右侧插入一个或多个元素
🍃 RPOP key count
:移除并返回列表右侧的第一个元素(count:取的个数)
🍃 LRANGE key star end
:返回一段角标范围内的所有元素
🍃 BLPOP
和 BRPOP
:与 LPOP 和 RPOP 类似(区别:当没有元素时,会等待指定时间,而不是直接返回 nil)
❓ 如何利用 List 结构模拟一个栈?
入口和出口在同一边【后进先出】
❓ 如何利用 List 结构模拟一个队列?
入口和出口在不同边【先进先出】
❓如何利用 List 结构模拟一个阻塞队列?
① 入口和出口在不同边
② 出队时采用 BLPOP 或 BRPOP
九、Set 类型
🍀 Redis 的 Set 结构与 Java 中的 HashSet 类似,可看做是一个 value 为 null 的 HashMap
🍀 因为也是一个 Hash 表,所以具备与 HashSet 类似的特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
🌱 SADD key member ...
:向 set 中添加一个或多个元素
🌱 SREM key member ...
: 移除 set 中的指定元素
🌱 SCARD key
: 返回 set 中元素的个数
🌱 SISMEMBER key member
:判断一个元素是否存在于 set 中
🌱 SMEMBERS key
:获取 set 中的所有元素
🌱 SINTER key1 key2 ...
:求 key1 与 key2 的交集(key1 和 key2 都有的元素)
🌱 SDIFF key1 key2 ...
:求 key1 与 key2 的差集
🌱 SUNION key1 key2 ...
:求 key1 和 key2 的并集
将下列数据用 Redis 的 Set 集合来存储:
🍃 张三的好友有:李四、王五、赵六
🍃 李四的好友有:王五、麻子、二狗
利用 Set 的命令实现下列功能:
🍃 计算张三的好友有几个
🍃 计算张三和李四有哪些共同好友
🍃 查询哪些人是张三的好友却不是李四的好友
🍃 查询张三和李四的好友总共有哪些人
🍃 判断李四是否是张三的好友
🍃 判断张三是否是李四的好友
🍃 将李四从张三的好友列表中移除
十、SortedSet 类型(可排序)
☃️ Redis 的 SortedSet 是一个可排序的 set 集合
☃️ 与 Java 中的 TreeSet 有些类似
☃️ 但底层数据结构却差别很大
☃️ SortedSet 中的每一个元素都带有一个 score 属性
,可以基于 score 属性对元素排序
☃️ 底层实现是跳表(SkipList)加 Hash表
☃️ SortedSet 具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
☃️ 因为 SortedSet 的可排序特性,经常被用来实现排行榜功能
🌼 ZADD key score member
:添加一个或多个元素(若已存在,则更新其 score 值)
🌼 ZREM key member
:删除指定元素
🌼 ZSCORE key member
: 获取指定元素的 score 值
🌼 ZRANK key member
:获取指定元素的排名
🌼 ZCARD key
:获取 key 中的元素个数
🌼 ZCOUNT key min max
:统计 score 值在给定范围内的所有元素的个数
🌼 ZINCRBY key increment member
:让指定元素自增,步长为指定的 increment 值
🌼 ZRANGE key min max
:按照 score 排序后,获取指定排名范围内的元素
🌼 ZRANGEBYSCORE key min max
:按照score
排序后,获取指定 score
范围内的元素
🌼ZDIFF、ZINTER、ZUNION
:求差集、交集、并集
🌼 注意:所有排名默认是升序,如果要降序则在命令的【Z】后面添加 REV
将班级的下列学生得分存入 Redis 的 SortedSet 中:
Jack 85, Lucy 89, Rose 82, Tom 95, Jerry 78, Amy 92, Miles 76
并实现下列功能:
❓ 删除 Tom 同学
❓ 获取 Amy 同学的分数
❓ 获取 Rose 同学的排名
❓ 查询 80 分以下有几个学生
❓ 给 Amy 同学加2分
❓ 查出成绩前 3 名的同学
❓ 查出成绩 80 分以下的所有同学