【Redis】超详细基础入门学习
Redis
一、初始学习
1.NoSQL与SQL的差异
1)表的结构差异
- SQL(Structured Query Language)关系型数据库:它的表结构通常是比较固定的结构,用于约束插入的数据形式(比如数据类型、长度),一旦设计完毕,基本上不会再改变表结构,插入的数据需要严格符合表规定的结构,同时表格也会对数据进行校验。
- NoSQL非关系型数据库:数据以键值对的形式存储,key和value的形式都可以自定义形式,要求没有那么严格。
2)数据关联性
- SQL: 可以在表中记录与其他表的联系
- NoSQL:通过JSON的形式记录一条数据中包含的全部信息(缺点:可能会存储重复的一些数据)
数据库不会维护数据之间的关联性,需要程序员手动实现数据关联性
3)查询语法
- SQL:固定的语法结构,同一条SQL语句可以在不同的数据库中使用。
- NoSQL:没有统一的语法结构,较为灵活,但是通用性不强。
4)ACID
- SQL:在数据进行增删改查时有事务进行维护,可以保证原子性、一致性、隔离性等特性。
- NoSQL:无法满足强ACID特性。
5)总结
2.认识redis
1)redis基本特征
- 键值型(key-value):value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟、速度快(基于内存、IO多路复用、良好的编码)
- 支持数据持久化(定期会将内存数据存储到磁盘中)
- 支持主从集群、分片集群
- 支持多种语言客户端
2)redis安装
1.Windows安装
博客地址
压缩包下载解压之后
- 1.先双击运行
redis-server.exe
- 2.再双击运行
redis.cli.exe
就能运行成功了
2.Linux安装(ubantu云服务器下)
- 1.使用Xshell连接到服务器
- 2.更新安装文件
apt update
- 3.安装redis
apt install redis-server -y
- 4.测试
登录到redis:
redis-cli
测试
通过ping
命令看是否连通:返回PONG
说明连通
info
查看当前安装的redis版本等信息
- 5.修改配置
在root下执行:
vim /etc/redis/redis.conf
1.添加登录密码
在文件中添加一行:
requirepass 123456 #后面跟的是你设置的密码:这里演示为123456systemctl restart redis-server.service #重启使配置生效
重新进入redis,使用ping命令就需要登录验证
使用密码授权登录
auth 123456 #123456是你设置的密码
2.远程登录访问
在root下执行:
vim /etc/redis/redis.conf
进入conf文件之后:
输入:/bind
匹配查找到bind 127.0.0.1
,将它修改为bind 0.0.0.0
systemctl restart redis-server.service #重启使配置生效
这样远程也可以通过服务器的公网IP访问当前服务器下的redis:
(前提是服务器的安全组需要开发6379端口)
redis-cli -h 120.xx.xx.xx
也可以设置其他配置:
3) redis使用
1.命令行客户端
2)图形化界面客户端
二、redis常见命令
1.redis数据结构
使用help @<group> # 分组
去查看每个种类的通用命令
2.通用命令
- 1.
KEYS
:查看符合模板的所有key - 2.
DEL
:删除指定的key - 3.
EXISTS
:判断key是否存在 - 4.
EXPIRE
:给一个key设置有效期,有效期到期时,该key会被自动删除 - 5.
TTL
:查看一个key的剩余有效期,-1
为永久有效
通过help [command]可以查看一个命令的具体用法,例如:
3.String类型
- 1.
SET
:添加或者修改一个已经存在的一个String类型的键值对 - 2.
GET
:根据key获取String类型的value - 3.
MSET
:批量添加多个String类型的键值对 - 4.
MGET
:根据多个key获取多个String类型的value - 5.
INCR
:让一个整形的key自增1 - 6.
INCRBY
:让一个整形的key自增并指定步长,例如:incrby num 2让num值自增2 - 7.
INCRBYFLOAT
:让一个浮点型的key指定增长指定步长 - 8.
SETNX
:添加一个String类型的键值对,前提是这个key不存在,存在则不添加,与SET key value NX
效果一致 - 9.
SETEX
:添加一个String类型的键值对,并指定有效期,与SET key value EX time
效果一致
key的层级结构
redies的key允许多个单词形成层级结构,多个单词之间用:
隔开,格式如下:
项目名:业务名:类型:id
格式并非固定,可以根据自己的需求来删除或者添加词条
例如: 项目名叫animal,有dog和cat两种不同类型的数据,则可以定义成:
- dog相关的key:
animal:dog:1
- cat相关的key:
animal:cat:1
可以通过这种形式实现key的层级分离:
4.Hash类型
- String类型存储之后,如果某个字段需要修改,只能重新添加,或者删除,很不方便
- 而Hash类型能够将对象中的每个字段进行存储,当需要对单个字段进行CRUD(增删改查)时,可以直接找到对应字段进行修改
Hash类型常见命令:
HSET key field value
:添加或者修改hash类型key的field值HGET key field
:获取hash类型key的field值HMSET key [field value...]
:批量添加一个hash类型的key的field值HMGET key [field...]
:批量获取多个hash类型key的field值HGETALL
:获取一个hash类型的key中所有的field和valueHKEYS
:获取一个hash类型的key中的所有fieldHVALS
:获取一个hash类型的key中的所有valueHINCRBY
:让一个hash类型的key中的所有字段值自增并指定步长HSETNX
:添加一个hash类型的key的field值,前提是这个field不存在,否则不添加
5.List类型
redis中的List类型与Java中的LinkedList类型,可以看做是一个双向链表结构,既可以正向检索也可以反向检索
特征也与LinkedList类型:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
- 常用于存储一个有序的数据,比如:朋友圈点赞列表、评论列表等
List常用命令:
LPUSH key element...
:向列表左侧插入一个或多个元素LPOP key
:移除并返回列表左侧的第一个元素,没有则返回nil
RPUSH key element...
: 向列表右侧插入一个或者多个元素RPOP key
:移除并返回列表右侧第一个元素LRANGE key star end
:返回一段角标范围内的所有元素BLPOP
和BRPOP
:与LPOP
和RPOP
类似,只不过在没有元素时等待指定时间,而不是直接返回nil
,如果等到了元素则会返回该元素
烧烤:
- 模拟栈:插入元素使用LPUSH,弹出使用LPOP
- 模拟队列:插入元素使用LPUSH,弹出使用RPOP
- 模拟阻塞队列:保证出口和入口不在同一边,出队时采用BLPOP或者BRPOP
6.Set类型
redis的Set结构与Java中的Hashset类似,可以看做是一个value为null的HashMap
特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
Set常用命令:
SADD key member...
:向set中添加一个或者多个元素SREM key mbmber...
:移除set中的指定元素SCARD key
:返回set中元素的个数SISMEMBER key member
:判断一个元素是否存在于set中SMEMBERS
:获取set中所有元素SINTER key1 key2...
: 求key1与key2的交集SDIFF key1 key2...
:求key1与key2的差集SUNION key1 key2...
: 求key1与key2的并集
7.SortedSet类型
redis的SortedSet是一个可排序的set集合,与Java中的TressSet有些类似,但底层数据结构却差别很大。
SortedSet中每一个元素都带有一个score属性,可以基于score属性对元素进行排序,底层的实现是一个跳表(SkipList)加Hash表。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
- 经常用于实现排行榜这样的功能
SortedSet常用命令:
ZADD key score member
: 添加一个或者多个元素到sortedset,如果已经存在则更新其score
值ZREM key member
: 删除sortedset中的一个指定元素ZSCORE key member
: 获取soretedset中的指定元素的score
值ZRANK key member
: 获取sortedset中的指定元素的排名ZCARD key
: 获取sortedset中的元素个数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
: 求差集、交集、并集- 注:所有的排名默认都是升序,如果需要降序则在
命令的Z后面添加REV
即可,比如ZREVADD
三、redis的Java客户端
1.Jedis
快速入门
jedis官网地址
jedisTest.java
:
package com.jedislearn.test;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;public class jedisTest {private Jedis jedis;@BeforeEachvoid setUp() {//1.建立连接jedis = new Jedis("120.55.71.43", 6379);//2.设置密码jedis.auth("123456");//3.选择库jedis.select(0);}@Testvoid testStirng() {//存入数据String result = jedis.set("name", "张三");System.out.println("result = " + result);//获取数据String name = jedis.get("name");System.out.println("name = " + name);}@AfterEachvoid tearDown() {if (jedis != null) {jedis.close();}}
}
碰到的小问题
我这里使用的是云服务的redis连接
在测试时出现无法连接到云服务器的情况,这种情况下:
先去查看云服务器上redis有没有正确启动:
ps aux | grep redis
结果显示:
redis 804 0.1 0.6 67212 11044 ? Ssl 19:58 0:00 /usr/bin/redis-server 0.0.0.0:6379
root 1723 0.0 0.1 6480 2328 pts/0 S+ 20:01 0:00 grep --color=auto redis
说明redis在服务器上已经启动了,并在6379端口监听
那么下一步检测云服务器防火墙:
sudo ufw status
结果显示:
Status: activeTo Action From
-- ------ ----
22/tcp ALLOW Anywhere
2233/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
2233/tcp (v6) ALLOW Anywhere (v6)
可以看到6379端口并没有开发出来
于是
sudo ufw allow 6379
再次查看状态:
root@iZbp18t4knye9ebutil345Z:~# sudo ufw allow 6379
Rule added
Rule added (v6)
root@iZbp18t4knye9ebutil345Z:~# sudo ufw status
Status: activeTo Action From
-- ------ ----
22/tcp ALLOW Anywhere
2233/tcp ALLOW Anywhere
6379 ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
2233/tcp (v6) ALLOW Anywhere (v6)
6379 (v6) ALLOW Anywhere (v6)
此时redis端口就向外开放了,可以远程连接了。
*还有一种情况就是云服务器的安全组没有添加6379端口,那么是需要手动添加的。
JedisConnectionFactory
:
package com.jedislearn.jedis;import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;public class JedisConnectionFactory {private static final JedisPool jedisPool;static {//配置连接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(8); //连接池中最多支持的连接poolConfig.setMaxIdle(8); //连接预备的最大连接数poolConfig.setMinIdle(0); //当长时间没有连接时,连接池维护的最小连接poolConfig.setMaxWaitMillis(1000); //当连接池没有连接可用时,等待的时间,直到有空闲连接为止。(-1)为一直等待//创建连接池对象jedisPool = new JedisPool(poolConfig, "120.55.71.43", 6379, 1000, "123456");}public static Jedis getJedis() {return jedisPool.getResource();}}
jedisTest.java
:
package com.jedislearn.test;import com.jedislearn.jedis.JedisConnectionFactory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;import java.util.Map;public class jedisTest {private Jedis jedis;@BeforeEachvoid setUp() {//1.建立连接
// jedis = new Jedis("120.55.71.43", 6379);jedis = JedisConnectionFactory.getJedis(); //调用连接池工具,从连接池中获取一个连接//2.设置密码jedis.auth("123456");//3.选择库jedis.select(0);}@Testvoid testString() {//存入数据String result = jedis.set("name", "张三");System.out.println("result = " + result);//获取数据String name = jedis.get("name");System.out.println("name = " + name);}@Testvoid testHash() {//插入数据jedis.hset("user:1", "name", "lisi");jedis.hset("user:1", "age", "12");//获取String name = jedis.hget("user:1", "name");System.out.println("name = " + name);Map<String, String> map = jedis.hgetAll("user:1");System.out.println(map);}@AfterEachvoid tearDown() {if (jedis != null) {jedis.close();}}
}
2.SpringDataRedis
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis
快速入门
*注:上述内容以及图片均来自黑马程序员的redis视频课程学习笔记,仅作为学习交流,不用作商业用途,如有侵权,联系删除。