Redis学习笔记之基础篇
Redis 学习笔记
基础篇
认识 Redis
1. 认识 NoSQL
NoSql可以翻译做Not Only Sql(不仅仅是SQL),或者是No Sql(非Sql的)数据库。是相对于传统关系型数据库而言,有很大差异的一种特殊的数据库,因此也称之为非关系型数据库。
(1) 结构化与非结构化
① 传统关系型数据库是结构化数据,每一张表都有严格的约束信息:字段名、字段数据类型、字段约束等等信息,插入的数据必须遵守这些约束:

② 而NoSql则对数据库格式没有严格约束,往往形式松散,自由。可以是键值型、文档型、图格式。
(2) 关联和非关联
① 传统数据库的表与表之间往往存在关联,例如外键:

② 而非关系型数据库不存在关联关系,要维护关系要么靠代码中的业务逻辑,要么靠数据之间的耦合:
1 | { |
(3) 查询方式
① 传统关系型数据库会基于Sql语句做查询,语法有统一标准;
② 不同的非关系数据库查询语法差异极大,五花八门各种各样。

(4) 事务
① 传统关系型数据库能满足事务ACID的原则。

② 而非关系型数据库往往不支持事务,或者不能严格保证ACID的特性,只能实现基本的一致性。
(5) 总结
| SQL | NoSQL | |
|---|---|---|
| 数据结构 | 结构化(Structured) | 非结构化 |
| 数据关联 | 关联的(Relational) | 无关联的 |
| 查询方式 | SQL查询 | 非SQL |
| 事务特性 | ACID | BASE |
| 存储方式 | 磁盘 | 内存 |
| 扩展性 | 垂直 | 水平 |
| 使用场景 | 1)数据结构固定 2)对一致性、安全性要求不高 | 1)数据结构不固定 2)相关业务对数据安全性、一致性要求较高 3)对性能要求 |
2. Redis 桌面客户端
(1) Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:
1 | redis-cli [options] [commonds] |
其中常见的options有:
-h 127.0.0.1:指定要连接的redis节点的IP地址,默认是127.0.0.1-p 6379:指定要连接的redis节点的端口,默认是6379-a 123321:指定redis的访问密码
Redis 常见命令
1. Redis 数据结构
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5中常用的数据类型
- 字符串:String
- 哈希:Hash
- 列表:List
- 集合:Set
- 有序集合:Sorted Set
2. Redis命令-String命令
(1) 介绍
String 类型,也就是字符串类型,是Redis中最简单的存储类型。其value是字符串,根据字符串的格式不同,又可以分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自减操作

说明:
Redis 没有原生的 “整数类型” “浮点类型” 存储结构,String 类型的所有 value,底层都以 简单动态字符串(SDS) 这种字节数组形式存储。
- 表格中
num的10:底层存的是字符'1'和'0'的字节,不是编程语言里占 4 字节的整数 10; - 表格中
score的92.5:底层存的是字符'9''2''.''5'的字节,不是浮点型的二进制存储; - 只有格式上的区别,存储本质完全一致。
(2) String 的常见命令有:
- SET:添加或者修改已经存在的一个String类型的键值对
- GET:根据key获取String类型的value
- MSET:批量添加多个String类型的键值对
- MGET:根据多个key获取多个String类型的value
- INCR:让一个整型的key自增1
- INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
- SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行
- SETEX:添加一个String类型的键值对,并且指定有效期
① SET 和 GET:如果key不存在则是新增,如果存在则是修改
1 | 127.0.0.1:6379> set name Rose //原来不存在 |
② INCR 和 INCRBY 和 DECY
1 | 127.0.0.1:6379> get age |
3. Redis命令-Key的层级结构
(1) 存在的问题
需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1,此时如果使用id作为key,那就会冲突了,该怎么办?
(2) 解决方案
① Redis的key允许有多个单词形成层级结构,多个单词之间用’:’隔开,格式如下:

② 例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:
- user相关的key:heima:user:1
- product相关的key:heima:product:1
4. Redis命令-Hash命令
(1) 优势
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:

(2) 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
- HINCRBY:让一个hash类型key的字段值自增并指定步长
- HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
① HSET 和 HGET
1 | 127.0.0.1:6379> HSET heima:user:3 name Lucy//大key是 heima:user:3 小key是name,小value是Lucy |
② HKEYS和HVALS
1 | 127.0.0.1:6379> HKEYS heima:user:4 |
5. Redis命令-List命令
(1) 特征
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
(2) List的常见命令
- LPUSH key element … :向列表左侧插入一个或多个元素
- LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
- RPUSH key element … :向列表右侧插入一个或多个元素
- RPOP key:移除并返回列表右侧的第一个元素
- LRANGE key star end:返回一段角标范围内的所有元素
- BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

6. Redis命令-Set命令
(1) 特征
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
(2) 常见的命令
| 命令 | 描述 |
|---|---|
| SADD key member1 [member2] | 向集合添加一个或多个成员 |
| SMEMBERS key | 返回集合中的所有成员 |
| SCARD key | 获取集合的成员数 |
| SINTER key1 [key2] | 返回给定所有集合的交集 |
| SUNION key1 [key2] | 返回所有给定集合的并集 |
| SDIFF key1 [key2] | 返回给定所有集合的差集 |
| SREM key member1 [member2] | 移除集合中一个或多个成员 |

7. Redis命令-SortedSet类型
(1) 特征
Sorted Set有序集合是String类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score) 。Redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。
(2) 常见命令
- ZADD key score member:添加一个或多个元素到sorted set ,如果已经存在则更新其score值
- ZREM key member:删除sorted set中的一个指定元素
- ZSCORE key member : 获取sorted set中的指定元素的score值
- ZRANK key member:获取sorted set 中的指定元素的排名
- ZCARD key:获取sorted set中的元素个数
- ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
- ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment值
- ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
- ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
- ZDIFF、ZINTER、ZUNION:求差集、交集、并集三、
Redis的Java客户端 - Jedis(了解即可)
1. 操作步骤
① 引入依赖
1 | <!--jedis--> |
② 建立连接
新建一个单元测试类,内容如下:
1 | private Jedis jedis; |
③ 测试
1 |
|
④ 释放资源
1 |
|
2. Jedis连接池
(1) 创建Jedis的连接池
1 | static { // 静态代码块:类加载时自动执行,只执行一次 |
Redis的Java客户端-SpringDataRedis
1. 介绍
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

2. 快速入门
① 需要导入它的maven坐标
1 | <!--Spring Boot-redis的依赖包--> |
② 配置文件
1 | spring: |
③ 测试代码
1 |
|
3. 数据序列化器
(1) 自定义RedisTemplate的序列化方式,代码如下:
1 |
|
说明:
之所以要写 HashKey 和 HashValue,是因为Redis 里的 Hash 类型,就像一个「嵌套的 Map」:
- 顶层结构:
RedisKey(顶层Key) → Hash结构(顶层Value) - Hash 内部结构:
HashKey → HashValue
4. StringRedisTemplate
(1) 存在的问题
默认情况下,RedisTemplate 使用的序列化器(比如 JdkSerializationRedisSerializer)会把对象的 完整类信息(class 类型) 也写入到 JSON 结果中,再存入 Redis。
比如一个 User 对象,序列化后可能变成这样:
1 | { |
这里的 "@class": "com.example.User" 就是额外的类信息,它会占用不必要的内存空间。
(2) 解决方案
- 先使用
ObjectMapper把对象手动转换成纯 JSON 字符串(不带 class 信息)。 - 再用
StringRedisTemplate把这个 JSON 字符串存入 Redis。 - 读取时,先从 Redis 取出 JSON 字符串,再手动用 Jackson 把它反序列化为对象。
(3) 代码实现
1 |
|
5. Hash结构操作
1 |
|




