Redis基础篇

认识 NoSQL

NoSQL,非关系型数据库,它们不保证关系型数据库的ACID特性(原子性、一致性、隔离性、持久性)。NoSQL概念在2009年被提出来,NoSQL最常见的解释是“non-relational”,"No noly SQL"也被很多人接受。NoSQL被我们用来最多的当作 key - value存储,当然还有其他文档型的、列存储、图型数据库、XML数据库等。

NoSQL与SQL的对比

1. SQL具有结构化,NoSQL不具有结构化

意思:

SQL的结构化固定的以表的形式存储,允许添加约束。

NoSQL的结构化是多变的,可以使用键值对的形式(key,value),也可以通过 文本的形式(Document),还可以通过图的形式(Graph)

 2. SQL具有关联性,而NoSQL不具有关联性

SQL:可以通过外键的形式,来确定哪个用户买了商品

NoSQL:由于NoSQL不具有关联性,所有一般使用  Json 的格式,来确定用户购买哪些商品

SQL:

NoSQL:

 3. SQL具有大部分固定的 SQL 查询语法,而 NoSQL 的查询语句都不相同

比如:

1 -- SQL 中查询时语法
2 SELECT * FROM TBL_USER WHERE ID = 1;
3 
4 -- NoSQL中的查询根据数据库的不同分为几种。
5 -- Redis:
6 get user:1
7 --MongDB:
8 db.users.find({_id:1})

 4. SQL的事务支持ACID,NoSQL的事务仅仅只能满足基本的事务功能

 总结

  SQL NOSQL
数据结构化  结构化  非结构化
数据关联  无关联的 无关联
事务特性 ACID 非SQL
存储方式 磁盘 内存
扩展性 垂直   水平
使用场景

1)数据结构固定

2)相关业务对数据安全性、一致性要求高

1)数据结构不固定

2)对一致性、安全性要求不高

3)对性能要求高

 

 

 

 

 

 

 

 

 

 

 

 

Redis

redis就是一个非关系型数据库,Redis的特点

1️⃣键值型,value 支持多种不同的数据结构,功能丰富

2️⃣单线程,每个命令具有原子性

3️⃣低延迟速度快基于内存、IO 多路复用、良好的编码

4️⃣支持数据持久化

5️⃣支持主从集群、分片集群

6️⃣支持多语言客户端


这里讲了Redis的厉害之处,后面将简单讲解一下  Redis 的基本数据结构及其命令

Redis命令

Redis是一个  key-value  的数据库,key一般是 String 类型,不过 value 的类型多种多样。

 1 String:hello  world(字符串)
 2 Hash:{name: "Jack", age: 21}(哈希)
 3 List:[A -> B -> C -> D] (有序集合, 可以重复)
 4 Set:{A, B, C}(无序集合, 不能重复的)
 5 SortedSet(ZSET):{A: 1, B: 2, C: 3}(可排序的集合)
 6 GEO:{A: (120.3, 30.5)}(坐标)
 7 BitMap:01101101110101011
 8 HyperLog: 01101101110101011

注意: 1~5属于基本类型、6~8属于特殊类型

 图片如下:

 学习Redis时,命令不记得没太大关系,但是要学会自己查看命令,查看命令的方式:

通过 help命令查看:

通过官方文档进行查看:


Redis通用命令

1. KEYS:查看符合模板的所有key,不建议再生产环境设备上使用,可以搭配 通配符 进行使用

 2. DEL:删除一个指定的 key返回 1 代表删除成功

 3. EXISTS:判断 key 是否存在(1代表存在, 0代表不存在

 4. EXPIRE: 给一个 key 设置有效期,有效期到该 key  会被自动删除

 5. TTL:查看一个 key 的剩余有效期(-2代表已过期

 注意:

一开始设置的key,如果没有指定 ttl 过期时间默认为 -1 代表永久


 

String 类型

String 类型,就是 字符串类型,是 Redis 中最简单的存储类型。

其 value 是字符串,不过根据字符串格式不同,分为 3类

1️⃣String:普通字符串

2️⃣int:整数类型,可以做自增、自减操作

3️⃣float:浮点类型,可以做自增、自减操作

注意:字符串类型的最大空间不能超过 512m

  • String:普通字符串
  • int:整数类型,可以做自增、自减操作
  • float:浮点类型,可以做自增、自减操作

不管是哪种格式底层都是字节数组形式存储,只不过是编码方式不同。

 

String常见命令

1️⃣设置种类 key 的命令:

1. SET添加或者修改已存在的一个 String 类型的键值对

 如果设置的key重名时,则进行替换

 

 2. MSET:批量添加多个 String  类型的 value 

 

 3. SETNX:添加一个 Stirng 类型的键值对,前提是这个 key 不存在,否则不执行

 注意:

①这个 setnx  k1 123 为什么会返回0 执行不成功呢

-- 可以看到上面的命令,k1 是存在的,所以添加失败,返回0
get k1 

② SETNX  = SET NX 这两个命令效果是一致的

4. SETEX:添加一个 String 类型的键值对,并且指定有效期

语法:SETEX key 秒 value

 注意: 

SETEX  =  SET EX (SETEX 命令     与   SET 命令  EX  参数效果一致)

 

2️⃣获取key的命令:

1. GET:根据 key  获取 String  类型的 value

 

2. MGET:批量获取多个 key 对应的 value 值

 

3️⃣功能型,自增、自减的命令:

1. INCR:让一个整形的 key 自增 1

 

 2. INCRBY:让一个整形的 key 自增指定的步长

例如:incrby num 2:让 num  值自增2

 注意:

这个数字不一定要 正数 ,如果为 负数 则表示自减指定步长

 

5. INCRBYFLOAT:让一个浮点类型的数字 自增 并指定步长

同理:也可以是负数


 

思考

Redis 并没有类似 MySQL 中的 Table 概念,我们要如何进行区分不同类型的 key 呢?

场景:需要存储用户、商品信息到 Redis中,有一个用户的id为1,有一个商品id恰好也是1,要怎么办?

答案/解决方案:

Redis的key允许有多个单词进行层级结构,多个单词之间用 ":" 隔开(这个可以按照公司的要求来),格式如下:

项目名:业务名:类型id

例子:

  •  user相关的key:gzyhrc:user:1
  • product相关的key:gzyhrc:product:1

 Hash类型

 Hash类型,是无序字段,类似于 HashMap结构

String 类型 与 Hash 类型比较

  • String 类型,如果存储的内容为  json 格式,也仅仅是一个字符串存储起来,这样就导致,如果我相对 json 格式存储 某个 属性进行修改时只能删除后重新填写
  • Hash 类型,对于 json 格式的数据,可以指定某个属性,并对他进行直接操作,无需这样复杂的操作,对每单个字段都可以进行  CRUD 操作

Hash常见命令

1️⃣设置 Hash类型key的field的值

1. HSET key filed  value单个添加或者修改 hash类型的 field 的值

 

 2. HMSET key field value [field value]:批量添加多个 hash 类型 key 的field 的值

 

 3. HSETNX key field value:添加一个 hash类型   key 的  field 值,前提是这个field不存在否则不执行

 

2️⃣获取key的filed值

1. HGET key field获取一个 hash 类型 key 的field 的值

 

2. HMGET key field  [field]批量获取多个 hash 类型 key的field 的值

 

3. HGETALL key:获取一个 hash 类型的 key 中所有的 field value

 

 4. HKEYS key:获取一个 hash类型的key中的所有的field

 

 5. HVALS key:获取一个  hash类型的key中的所有value

 

3️⃣功能性自增、自减命令:

1. HINCRBY key field  increment:让一个hash类型的key的field 值 自增并指定步长

注意:如果指定步长为负数,则自减


 

List类型 

概念:Redis中的List类型与Java中的LinkedList类似,可以看做时一个双向链表结构,既可以支持正向检索和也可以反向检索。

特征与LinkedList类似:

  1. 有序
  2. 元素可以重复
  3. 插入和删除快
  4. 查询速度一版
  5. 常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

List常见命令

1️⃣设置元素命令:

 1. LPUSH key element ........:向列表左侧插入一个或多个元素

 2.  RPUSH key element:向列表右侧插入一个或多个元素

 

2️⃣获取元素命令:

 1. LPOP key移除并返回列表左侧第一个元素,没有返回 nuil

 2. RPOP key移除并返回列表右侧第一个元素,没有则返回nuil

 3. LRANGE key start  end:返回一段索引范围内容的所有元素

 4. BLPOP 和 BRPOP:与LPOP 和 RPOP类似,只不过在没有元素时候等待指定时间,而不是直接返回null


 

思考

1. 如何利用 List 结构模拟出一个栈

答案:只需要考虑,入口和出口 在同一边即可,意思:要么都用 lpush/lpop要么都用 rpush/rpop

2. 如何利用 List 结构模拟出一个队列

答案:只需要考虑,入口和出口 不同一边即可,意思:要么 lpush/rpop要么 rpush/lpop

3.  如何利用 List 结构 模拟一个阻塞队列

    • 队列要求:入口和出口不同边
    • 阻塞要求:出队时采用 BLPOP 和 BRPOP

 

SET 类型

Redis 的 Set 结构与 Java中的 HashSet 类似,可以看做是一个 value 为 null 的 HashMap。

特点:

  1. 无序
  2. 元素不可重复
  3. 查找快
  4. 支持交集、并集、差集等功能,适合于:发现好友列表等场景

 

Set常见命令

1️⃣设置元素命令:

1. SADD key member ......:向 set中添加一个或者多个元素

 

2️⃣获取元素命令:

2. SREM key member .....移除 set 中的指定元素

 

3️⃣判断元素是否存在于set中:

3. SISMEMBER  key member .....判断一个元素是否存在于 set 中

如果不存在,则返回0

 

4️⃣返回set中元素的个数:

4. SCARD   key返回set 中元素的个数

 

5️⃣获取key1和key2 的交集:

5. SINTER key1  key2 ....:求出key1 和 key2  的交集

 

6️⃣获取key1与key2的差集:

6. SDIFF key1 key2 .....:求出key1 和 key2 的差集

 注意:如果 hrc:set:2在前面,即拿 hrc:set:2 的差集

 

7️⃣:求获取key1和key2的并集

7. SUNION key1 key2......


 

练习题

前提:将下列的数据用Redis的Set集合来存储:

  1. 张三的好友有:李四、王五、赵六
  2. 李四的好友有:王五、麻子、二狗
1 -- 张三好友有:李四、王五、赵六 
2 sadd zs lisi wangwu zhaoliu
3 -- 李四好友有:王五、麻子、二狗 
4 sadd ls wangwu mazi ergou

利用Set的命令实现下面的功能:

1. 计算张三好友个数

scard zs

2. 计算张三和李四有哪些共同好友

sinter zs ls

3. 查询哪些人是张三的好友却不是李四的好友

sdiff zs ls

4. 查询张三和李四的好友总共有哪些人

sunoin zs ls

5.  判断李四是否是张三的好友

sismember zs lisi

6. 判断张三是否是李四的好友

sismember ls zhangsan

7. 将李四从张三的好友列表中移除

srem zs lisi

SortedSet类型

Redis 的 SortedSet 是一个可排序的 set 集合,与Java中的 TreeSet 有些类似,但底层数据结构差别很大。SortedSet中的每一个元素都带一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表

SortedSet具有下列特性:

  1. 可排序,经常用于实现排行榜这样的功能
  2. 元素不重复
  3. 查询速度快

 SortedSet常见命令

1. ZADD key score  member  :添加一个或多个元素倒 sorted set,如果已经存在更新其score值

 

 2. ZREM key member删除  sorted set中的一个指定元素

 

3. ZSCORE key member获取 sorted set 中的指定元素的score值

 

 4. ZRANK key member:获取sorted set 中指定元素的排名

 

5. ZCARD key:获取sorted set 中的元素个数

 

6. ZCOUNT key min max统计 score 值给定范围内的所有元素的个数

举个例子:判断score 值的给定的 [0,1]范围内的值,只有一个app

 

7. ZINCRBY  key increment member:让sorted  set中的指定元素自增步长为指定的increment值

举个例子:app的score值,从1变成 2.5

 

8. ZRANGE key min max:按照score排序后,获取指定排名范围内的元素

举个例子:查询出第三名、第四名、第五名的元素,由于这里没有第五个元素,所有返回只有两个元素

注意:

下标是根据0开始算起的

 

9. ZRANGEBYSCORE  key min max按照score 排序后,获取指定score范围内容的元素

举个例子:查询介于分数在2~4之间的元素

 

10. 求差集、交集、并集

差集

ZDIFF 命令用于计算多个有序集合的差集,即返回存在于第一个集合但不存在于其他集合中的元素。

语法:ZDIFF numkeys key [key ...] [WITHSCORES]

  • numkeys:参与计算的集合数量
  • key:有序集合的键名
  • withscores:可选参数,表示是否返回元素的分数

交集

ZINTER 命令用于计算多个有序集合的交集,并可以指定聚合方式(如求和、最小值、最大值)

语法:ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

  •  destination:存储结果的键名
  • numkeys:参与计算的集合数量
  • key:有序集合的键名
  • weights:可选参数,为每个集合指定权重
  • aggregate:可选参数,指定集合方式(sum、min、max)

并集

ZUNION 命令用于计算多个有序集合的并集,并可以指定聚合方式(如求和、最小值、最大值)

语法:

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

  •  destination:存储结果的键名
  • numkeys:参与计算的集合数量
  • key:有序集合的键名
  • weights:可选参数,为每个集合指定权重
  • aggregate:可选参数,指定集合方式(sum、min、max)

 

SortedSet的练习

将班级的下列学生得分存入Redis的SortedSet中:

Jack 85,Lucy 89,Rose 82,Tom 95,Jerry 78,Amy 92,Miles 76

zadd score Jack 85 Lucy 89 Rose 82 Tom 95 Jerry 78 Amy 92 Miles 76

练习一:删除Tom同学

zrem score Tom

练习二:获取Amy同学的分数

zscore score Amy

练习三:获取Rose同学的排名

排名第三名,因为从0开始排

zrank score Rose

降序的方式:

ZREVRANK score Rose

练习四:查询80分一下有几个同学

zcount  score 0 80

练习五:给Amy同学加 2分

zincrby score 2 Amy 

练习六:查出成绩前3名的同学

由于排名按照0开始算起的

zrange score 0 2

练习七:查出成绩80分一下的所有同学

zrangebyscore score 0 80

 

posted @ 2025-06-08 17:43  和哗  阅读(33)  评论(0)    收藏  举报