NoSQL概述以及redis数据类型总结

SQL与 NoSQL

  1. 数据结构
    在这里插入图片描述

Sql : 表结构固定、插入数据格式有严格规定,修改字段对业务影响很大

NoSql:结构松散、数据格式没有很强要求 。并且有多种类型存储方式:如 k_v 型、图类型、文档型 。修改影响小,
2. 数据关联性
在这里插入图片描述

  1. 查询方式
    在这里插入图片描述

  2. 事务特性
    在这里插入图片描述
    不同点总结:

在这里插入图片描述

redis简介

redis 全称 Remote Dictionary Server 远程字典服务器 诞生在2009年
特点

  • 键值(key-value)型,value支持多种不同数据结构,功能丰富
  • 单线程,每个命令具备原子性
  • 低延迟,速度快(基于内存 比磁盘快多倍、IO多路复用、良好的编码 C语言)。
  • 支持数据持久化 解决内存断电情况,确保磁盘安全性
  • 支持主从集群(数据备份 提升安全性、读写分离提升效率)、分片集群(提升存储容量,水平扩展)
  • 支持多语言客户端

redis安装

redis没有官方win版
centos安装步骤

  1. 确保具有gcc环境
yum install -y gcc tcl
  1. 选择一个安装目录 ,将redis安装包上传后 解压
tar -xzf redis-6.2.6.tar.gz
  1. 解压完成进入 软件目录
cd redis-6.2.6
  1. 开始编译
make && make install

安装完成

修改配置文件

启动 ./redis-server

默认前台启动(页面关闭即服务停止)、无法远程连接 、没有密码
修改配置文件 redis.conf,并以配置文件启动 ./redis-server ./redis.config

# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
# 密码,设置后访问Redis必须输入密码
requirepass 1234
======================================非必要修改==============================================
# 监听的端口
port 6379
# 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录
dir .
# 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
databases 3
# 设置redis能够使用的最大内存
maxmemory 1024mb
# 日志文件,默认为空,不记录日志,可以指定日志文件名 会产生在工作目录
logfile "redis.log"

redis客户端

redis提供三种使用方式

  1. 命令行
    在安装目录下:./redis-cli -h (ip 地址 默认 127.0.0.1) -p (端口号 默认 6379) -a (密码 可通过AUTH 后期添加)

  2. 图形化界面
    可以使用resp

  3. 编程语言

key的命名

【项目名】:【业务名】:【类型】:【key名】

五大数据类型

redis 是一种key-value型数据库 ,key为String ,但Value的类型很多 。一个库中 key不能重复

在这里插入图片描述
通用命令
适用于任何数据类型

  • keys :查看符合模板的所有key
    在这里插入图片描述
  • del 【key…】:删除一个key 支持同时传多个key
    在这里插入图片描述
  • exists 【key…】: 判断key是否存在
  • expire 【key】【time】 :给key设置有效期,到期自动删除、释放内存空间
    只能给已存在的key设置
    在这里插入图片描述
  • ttl 【key】:查询key存活剩余时间
    在这里插入图片描述

String类型

最简单的数据类型 ,值虽然也为String 但分为三类

在这里插入图片描述
String 类型常见命令

  • set 【key】【value】 存放一个键值对,如果存在则修改
  • get 【key】获取一个key的值
  • mset 【key】【value】… 支持同时存放多个键值对
  • mget【key…】同时获取多个key的值
  • incr 【key】 使得 int类型的值自增1
  • incrby【key】【value】使得 int类型的值每次自增 value value可以为负数,从而变为自减
  • incryByFloat 【key】【value】:同incryBy 前者用于整数类型,此用来float类型
    在这里插入图片描述
  • setnx【key】【value】:存放一个键值对 。但key之前不能存在
  • setex 【key】【time】【value】:在设置key时 为其指定过期时间

Hash类型 H

value为类似一种hashMap结构。redis是一种k_v的模型,v中在放置着一个HashMap结构
解决问题:在这里插入图片描述
结构

在这里插入图片描述
在这里插入图片描述

Hash常用命令:

  • hSet 【k】【【filed1】【v1】…】:添加或修改(存在则修改)v中的 个键值对
    在这里插入图片描述

  • hGet 【k】【filed】:获取单个K的V中 包含的某个K的V
    在这里插入图片描述

  • hmSet 【k】【【fiked1】【v1】…】:测试发现和hset功能相同,都是同时在一个key中添加多个键值对
    在这里插入图片描述

  • hmGet 【K】【filed】:取出单个K中 某个filed对应的值
    在这里插入图片描述

  • hGetAll 【k】:获取一个key中value (value 包含所有filed和value)
    在这里插入图片描述

    • hKeys 【K】:获取一个key中所有的 filed
      在这里插入图片描述
    • hVals 【K】:获取一个key中所有 filed对应的value
      在这里插入图片描述
  • hIncrBy:【k】【filed】【步长】
    在这里插入图片描述

  • hSetNX 【k】【【filed】【value】…】:只有filed不存在才会创建 (key可以存在)
    在这里插入图片描述

List类型 L R

value的值 是一个list 集合,底层类似于一个双向链表
value值 特点:
先后有序: 由于底层类似于双向链表,数据进行有先后顺序
数据可重复:对进入的值没有处理
插入和删除速度快,查询较慢:底层双向链表结构 ,插入、删除只需改变周围节点指向 而查询需要遍历节点

应用场景:对先后顺序有要求

常用命令:

  • Lpush 【key】【value…】:向左侧插入多个数据
    在这里插入图片描述
    在这里插入图片描述

  • Lpop 【key】:移除并返回左侧第一个元素
    在这里插入图片描述
    在这里插入图片描述

  • Rpush 【K】【value…】: 从右侧放入数据

  • Rpop 【K】
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • Lrange 【key】【start】【end】: 返回指定范围数据
    • Lrange 【key】0 , -1 表示获取key中所有元素

在这里插入图片描述

  • BLpop 【key】【time】 & BRpop 【key】【time】 :与Lpop 和Rpop相似 但当数据被移空时,会按设置时间等待 而不是直接返回(nil)
    在这里插入图片描述
    在这里插入图片描述
    问题
  1. 如何利用List结构模拟一个栈?
    在这里插入图片描述

在redis 的List类型中,使用从哪里进,从哪里出 即可
Rpush 和 Rpop 一组 Lpush 和Lpop 一组
2. 如何利用List结构模拟出一个队列
在这里插入图片描述
Rpush 和 Lpop 一组 、 Lpush 和Rpop 一组
3. 模拟阻塞队列
在队列的基础上,加上没有则等待特点
Rpush和BLpop一组、Lpush和BRpop 一组

Set类型 S

V中的值 可以看做没有value 只有key(不可重复、无序)的hashMap
特点:(hashMap中key的特点)

  • 无序 :用hash计算角标
  • 元素不可重复
  • 查找速度快:具有hash表
  • 支持 交集、并集、差集

常用命令:

  • sAdd 【K】【value…】:一次插入一个或多个数据

  • sRem 【K】【value】:移除一个或多个Key中指定元素
    在这里插入图片描述

  • Scard 【Key】:计算key中元素个数
    在这里插入图片描述

  • SisMember 【key】【value】:判断key中 某个value是否存在
    在这里插入图片描述
    运算命令

  • Sinter 【key1】【key2…】:求两个或多个集合间的交集
    在这里插入图片描述

  • Sdiff 【key1】【key2…】:求两个或多个集合间的差集

  • Sunion 【key1】【key2…】:求两个或多个集合间的并集
    命令练习案例
    在这里插入图片描述

SortedSet类型 Z

可排序的Set集合 。每个元素带有一个score属性,根据score进行排序(底层是通过跳表) 默认是升序(从小到大)
特点

  • 可排序:可排序的Set
    继承的set特点:
  • 查询数据快
  • 数据不重复
  • 支持 交集、并集、差集

使用场景:排行榜

常用命令

  • Zadd 【key】【【score】【value】…】:向key中 添加数据{score:value}
    在这里插入图片描述
    在这里插入图片描述

  • Zrem 【key】【value】 :根据key中 value进行删除
    在这里插入图片描述

  • Zscore 【key】【value】:查找key中value对用score值

  • 在这里插入图片描述

  • Zrank 【key】【value】:获取key中指定value的排名
    在这里插入图片描述

  • Zcard 【key】:获取key中元素个数

  • Zcount 【key】【分数min】【分数max】:按照score排序 分数范围,统计个数

  • Zrange 【key】【排名min】【排名max】:按照score排序 排名范围,获取元素

  • ZrangeByScore 【key】【分数 min】【分数max】:按照score 分数范围,获取元素

  • ZincrBy 【key】【步长】【value】:在key中找到value 将其Score 加上指定数值
    在这里插入图片描述
    降序排名(从大到小)
    在所以命令Z后加上 REV

运算命令

  • Zinter 【key1】【key2…】:求两个或多个集合间的交集
  • Zdiff 【key1】【key2…】:求两个或多个集合间的差集
  • Zunion 【key1】【key2…】:求两个或多个集合间的并集
    练习:
    在这里插入图片描述

其他数据类型

Stream

redis5.0 引入的新数据类型,一个功能完善的消息队列 。通常用于异步处理任务
生产者常用命令

  • xAdd 【队列的key】* 【【key】【value】…】
    每添加一次,即使有多个k_v对,也算一条消息
    在这里插入图片描述
  • xLen 【队列的key】 查看队列中消息的数量
    消费者常用命令
  • Xread count 【一次读取条数】block 【阻塞时间】 strames 【队列的key…】 $ 读取阻塞等待读取最新的消息
    在这里插入图片描述

Geo

用来存储和处理地理位置信息,本质是一个SortedSet
常用命令:

  • GeoAdd 【key】【【经度】【维度】【点的名称】…】 添加多个位置 点(通过经纬度确定)
    在这里插入图片描述

在这里插入图片描述

  • GeoDist 【key】【点1的名称】【点2的名称】(【单位 km】默认为m):查询两点间的距离
  • GeoHash 【key】【点的名称】: 将点的信息以hash字符串的形式,方便储存在这里插入图片描述
  • GeoPos 【key】【点的名字】:显示key中某个点的经纬度
  • GeoSearch 【key】fromLonLat 【中心的经度】【中心的维度】ByRadius 【距离值】【单位 m/ km 】(withDist 带上距离) :查询距离中心【形状 如圆形,方形】距离小于多少【距离值】【单位】的所有点,默认升序 6.2版本出现

bitMap

储存多个二进制信息,多用于签到
常用命令

  • setBit 【key】【要设置第几位】【置为 1 or 0】 :将key的第几个位置存入一个 0 或 1 。默认为0 (常用于签到
    在这里插入图片描述

  • getBit 【key】【要获取第几位】:获取key的第几位的bit值 (判断哪天有没有签到)

  • BitCount 【key】:统计key中1的个数 (查看一个月签到了多少天

  • BitField 【key】【操作类型 GET】【是否有符号 i:有符号 u:无符号】【读取位数】【从哪里开始读取】:常用无符号的一次读取多个位数的bit位 (常用获取具体的签到结果
    在这里插入图片描述

  • BitOp【key】:将bitMap的结果记性运算

  • bitOps【key】【0 or1】 :查找给定的bit值第一次出现的位置
    在这里插入图片描述

HyperLogLog

常用于进行UV统计。特点:可以记录统计亿级别的流量,而最大占用空间永远不超过16K。不能统计重复数据,且统计有有小于0.81%的误差

  • PfAdd 【key】 【value…(大量)】
  • PfCount 【key】统计key中的不重复的元素个数
  • PfMerge 【【key1】【key2】…】:将其他hyperLogLog类型的key进行合并。例如 每天统计访问用户数,最后合并可求出一个月的有多少个访问的用户数
    在这里插入图片描述h

redis编程客户端

java语言推荐三种客户端

  • jedis

    • 以命令作为方法名称,简单实用,学习成本低
    • 线程不安全 ,多线程需要基于连接池
  • lettuce(spring官方默认兼容):

    • 基于Netty实现,支持同步,异步和响应式编程 吞吐能力强
    • 线程安全
    • 支持redis哨兵模式、集群模式、管道模式
  • Redisson:

    • 不在于操作,基于redis实现的分布式
      springDateRedis 可兼容 jedis(额外导入jar包)和lettuce(默认兼容)

jedis使用

使用前 确保redis开启远程连接
导入依赖

jedis 依赖 
<dependency>   
	 <groupId>redis.clients</groupId>
	 <artifactId>jedis</artifactId>  
	 <version>3.7.0</version>
</dependency>
测试需要的:
<!--单元测试-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>

普通方式
2. 获取Jedis对象 ,创建连接(ip,port),进行测试

public class JedisTest {
    
    

    private Jedis jedis;

//    所有测试方法运行前初始化
    @BeforeEach
    void setUp(){
    
    
        String host="192.168.83.100";
        int port=6379;
        String password="1234";

        jedis=new Jedis(host,port);
        jedis.auth(password);
        jedis.select(0);
    }

//    所有测试方法运行后 执行
    @AfterEach
    void connectDown(){
    
    
        if(jedis!=null){
    
    
            jedis.close();
        }
    }

    @Test
    void testString(){
    
    
        jedis.set("name","jedis test!");
        System.out.println(jedis.get("name"));
    }
    
}

在这里插入图片描述
连接池方式
例:
使用jedis完成
在这里插入图片描述
在这里插入图片描述
由于Jedis线程不安全,并发环境需要使用 线程池 (频繁创建 销毁 消耗性能)由连接池创建对象
连接池工厂类

public class JedisConnectFactory {
    
    

    private static final JedisPool jedisPool;
    static {
    
    
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        String host="192.168.83.100";
        int port=6379;
        String password="1234";
        int timeout=1000;

//    设置总连接数
        poolConfig.setMaxTotal(8);

//   最大空闲连接    即使没有数据库连接时依然可以保持8个空闲的连接,而不被清除,随时处于待命状态
        poolConfig.setMaxIdle(8);

//      最小空闲连接
        poolConfig.setMinIdle(0);

        jedisPool= new JedisPool(poolConfig,host,port,timeout,password);
    }

    public static Jedis getJedis(){
    
    
        return jedisPool.getResource();
    }
}

连接对象创建


    private Jedis jedis;
    
    @BeforeEach
    void setUp(){
    
    
        jedis= JedisConnectFactory.getJedis();
    }

springDataRedis使用

特点:

  • 整合了 Lettuce和jedis
  • 提供 redisTemplate 封装形成统一API 底层来操作不同客户端
  • 支持 基于JDK,JSON,String的数据序列化(将对象变成 字符串 或 字节)和反序列化
  • 支持Redis哨兵 和 Redis集群
  • 支持Redis 发布订阅模型

在这里插入图片描述
使用方式:
引入springBoot依赖

   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-starter-data-redis</artifactId>
	 </dependency>
      <!--common-pool-->
      <dependency>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-pool2</artifactId>
      </dependency>
     

额外功能


      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
      </dependency>

在这里插入图片描述

  1. 进行配置
spring:
  redis:
    host: 192.168.83.100
    port: 6379
    password: 1234
    # 如果不配置连接池 连接池将不会生效
    lettuce:
      pool:
        max-active: 8  #最大连接
        max-idle: 8   #最大空闲连接
        min-idle: 0   #最小空闲连接
        max-wait: 100ms #连接等待时间
  1. 获取RedisTemplate 对象进行操作
	@Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void testString(){
    
    
        redisTemplate.opsForValue().set("name","spring-data-redis-string");
    }

在这里插入图片描述
问题
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
中
在这里插入图片描述

解决方式:

方案一 自动序列化
使用自定义的RedisTemplate K使用string序列化 V使用json序列化

@Configuration
public class RedisConfig {
    
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
    
    
        // 创建RedisTemplate对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());


        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);

        // 返回
        return template;
    }
}

注意:使用json序列化 需要导入 jackson-databind依赖 但springMv依赖会包含

效果

在这里插入图片描述

在这里插入图片描述

方式二 :手动序列化
与方式一不同 ,V也要采用使用String序列化
但不用自己制定,spring专门提供了将K_V都转为 String的 StringRedisTemplate
在这里插入图片描述

效果
在这里插入图片描述
注意
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_52889702/article/details/127508670
今日推荐