Redis关系型数据库

Redis 是一个高性能的键值对存储数据库,支持字符串、散列、列表、集合和有序集合等多种数据类型。其特点是速度快、易扩展,适用于缓存、计数器、分布式锁等场景。Redis 提供 RDB 和 AOF 两种持久化机制,确保数据在重启后仍能恢复。Java 开发者可以使用 Jedis 客户端与 Redis 进行交互。
摘要由CSDN通过智能技术生成

Redis

举例:Redirs缓存式数据库,比如双十一客户下单买东西,加入购物车中但是没买,数据库的库存这时候数量就会减一,但是这订单是有过期时间的,并没有持久化数据库中,缓存数据库中的数据适合那些经常查询并且不重要的数据

关系型数据库 数据直接存储到硬盘上的 IO mysql

缓存 基于内存

mybatis

非关系型数据库 NoSql Not Only Sql

关系型数据库和非关系型数据库(NoSql)的对比

优点:

  • 部署简易,免费开源,成本低

  • 查询速度快:nosql服务器将数据存储在内存中,关系型数据库是把数据存储在硬盘上

  • 存储数据的格式不相同:nosql存储数据的格式是key-value、文档型、图片,还可以存储对象和集合类型等,关系型数据库大多存储的是基本类型

  • 扩展性:在关系型数据库中进行多表查询时扩展性较差

主流的Nosql数据库产品

  • 键值(key-value) 存储数据库

    相关产品:Redis、DB、Tokyo

    应用: 内容缓存 主要是用于解决大量数据的高访问负载。

    数据模型:一系列键值对

    优势: 查询速度非常快

    劣势:存储的数据的缺少结构化

  • 列存储数据库:

    相关产品:Hbase

    典型应用:分布式的文件系统

    数据模型:以列簇的形式存储,将同一列的数据存储在一起

    优势: 查询速度非常快,可扩展性较强,容易进行分布式扩展

    劣势:功能局限性较大

  • 文档型数据库

    相关产品:MongoDB

    典型应用:web应用中 (和key-value类似,value是 结构化的)

    数据模型:一系列键值对

    优势:数据结构要求不严格

    劣势:查询性能不高,并且缺乏统一的查询的语法

  • 图形数据库 Graph

    相关产品: Graph Neo4J

    典型应用:社交网络

    数据模型:图结构

    优势:利用图结构进行相关优化算法

    劣势:需要对整个图做计算才能得出结果,不容易进行分布式集群的使用。

Redis概述

Redis产品是由C语言开发的一个开源的免费的键值对存储数据库,官方提供的数据库只有linux版

没有window版,对于50个并发,执行10万次请求,读的速度是110000次/s,写的速度在 81000次/s

它提供了多种键值类型满足多样化的需求,对于redis而言键的类型一般都是字符串,对应的值的类型一般有5中类型

  1. 字符串类型String

  2. 散列类型 hash

  3. 列表类型 list

  4. 集合类型 set

  5. 有序集合类型 sorted set

Redis的使用场景

  • 令牌的生成 Token 类似于session中的那个 sessionID

  • 短信验证码 code

  • 可以实现缓存查询数据 减轻数据库服务器的压力

  • Redis帮助实现计数器

  • 分布式锁

  • 延迟操作

  • 日志记录

  • 分布式集群的session的分离

安装

官方推荐的是在linux系统中进行安装的,同样也可以在window系统中进行安装

windows版不是官方版本,

我们的安装在Linux环境中进行安装

又因为Redis是由C语言写的,所以我们需要C语言的编译环境 ,先编译后再安装

启动后的默认端口是 【6379】

安装步骤待续。。。

Redis数据结构

  • redis是一种高级的key-value的数据库存储系统,其中value值支持5种数据类型 ,key数据类型一般都是string

    • 字符串类型 string

    • 散列类型 hash

    • 列表类型 list

    • 集合类型 set

    • 有序集合类型 sorted set

  • 对于redis的key值,如果定义的名称过长 ,查询效率会降低,按规范命名

命令

  • 测试连接是否成功 使用ping 成功会显示pong

  • redis默认在空间生成16个数据库,数据库的编号依次从0~15,默认使用的是0号数据库 select 0~15

    使用select index值 选择对应的数据库

  • 显示所有的key 使用 keys *

    • 使用指令 keys a?查询a开头的,长度为2的 key名称

  • 清空所有数据

  • 删除key 使用 del key名称 删除多个key值 del key1 key2。。。。

  • 校验key值是否存在 exists key 1代表存在 0代表不存在

  • 给key值进行重命名 rename key旧名称 key新名称

  • 给当前key值设置过期时间值,单位为秒 expire key 秒数

    • 查看过期key值剩余的时间值 ttl key 如果该key值存在显示剩余的时间,如果该key没有设置过期时间

      显示 -1 如果超时了 显示-2

  • 查看key的指定数据类型 type key 返回值 string hash set list zset

String类型

字符串类型是redis数据库中最基础最常用的数据类型,并且在redis中是二进制安全的,

该字符串类型可以接受任何类型的数据,在Redis中字符串类型的value值最多可以容纳的数据长度为512M

  • 设置键值对 set key value

  • 设置多个键值对 mset key1 value1 key2 value2 。。。。

  • 通过key值获取value值 get key 如果不存在返回【nil】

  • 删除key del key

  • 先获取key的值,再设置key的值 getset key value

  • 让key对应的value值增加相应的数字 incr key 默认增加1

  • 让key对应的value值减少1 decr key 默认减少1

  • 增加多个数值 incrby key 增加的数字

  • 减少多个数值 decrby key 减少的数字

  • 在key对应的value值后面追加信息 append key value 如果不存在直接新建附上相应的值

Hash类型

散列类型可以看做成String,key是String,value是一个map容器(key-value)

在hash类型中非常适合存储值(JavaBean)对象的信息

比如个人的信息 username age address password可以使用hash类型存储

每一个hash值可以存储42亿多个键值对信息

  • 赋值

    • hset key field value 给指定的key设定field/value键值对值 设置一个

    • hmset key field1 value1 field2 value2...... 给指定的key设置field/value对多个信息

  • 取值

    • hget key field 获取指定的key中field对应的value值

    • hmget key field1 field2 ....... 获取指定key中field1、field2对应的value值

    • hgetall key 获取指定key中所有的field/value值

  • 删除

    • hdel key field1 field2..... 删除指定key中field1、field2对应的值

    • del key 删除整个key对应的内容

  • 增加

    • hincrby key field 增加的数值

  • hexists key field 判断指定key中的field是否存在

  • hlen key 获取key所包含的field的数量

  • hkeys key 获取所有的key

  • hvals key 获取所有value

List类型

在Redis中,List类型是按照插入顺序排序的字符串链表

和数据结构中的普通链表一样,我们在头部(left)和尾部(right)添加新元素,在插入时,如果该键不存在

Redis将为该键创建一个新的链表。相反,如果链表中所有的元素均被移除,那么该键也将会从数据库中删除

List中可以包含的最大元素数量是42亿多个。

从 元素插入和删除的效率来看,如果我们是在链表的两端插入和删除,效率非常高;如果是从中间进行元素的插入和删除,效率较低

  • 两端添加

    • lpush key value1 value2 value3.... 通过指定的key存放多个value值,在list的头部插入所有的value值,

      如果该key不存在,该命令在插入之前创建一个与key关联的空链表,之后再把所有的value值在该空链表的头部依次插入,如果插入成功,返回元素的个数

    • rpush key value1 value2 value3...... 通过指定的key存放多个value值,在list的尾部添加元素

    • lpushx key value 仅当参数中指定的key存在时,在指定的key所关联的list的头部插入value值

    • rpushx key value 在list的尾部添加元素

       

  • 查看列表

    • lrange key start end 获取链表中从start到end的元素的值 start、end可以为负数,如果为-1表示链表尾部的元素,-2则表示倒数第二个 -3倒数第三个

  • 两端弹出

    • lpop key 返回并弹出指定key关联的链表中的第一个元素,即头部元素

    • rpop key 从尾部弹出元素

  • llen key 返回指定的key关联的链表中的元素的个数

  • linsert key before | after pivot value 在pivot元素的前或者后插入value值

Set类型

在Redis中,我们可以把set类型理解成没有排序的字符集合

和List类型一样,我们也可以在该类型的的数据值上进行添加、删除或者判断某一元素是否存在等操作

Set可包含的最大元素数是42亿多个

和List类型不一样的是,Set集合中不允许出现重复的元素

Set集合类型还可以在服务器端进行聚合计算操作,如 unions、intersection和differences

  • sadd key value1 value2 value3..... 向set中添加数据,如果value值重复,则不会二次添加

  • smembers key 获取key中所有的成员

  • srem key member1 member2.....删除set中指定的成员

  • sismember key member 判断参数中指定的成员是否在该set中存在,1表示存在,0表示不存在

  • scard key 获取key中成员的数量

  • srandmember key count 随机获取set中的一个成员 随机获取count个成员

  • 和集合相关

    • sdiff key1 key2 返回key1与key2中相差的成员 并且和key的顺序有关 返回的是差集

    • sdiffstore destination key1 key2 将key1、key2相差的成员存储在destination中

    • sinterstore destination key1 key2 将返回的交集存储在destination中

    • sunion key1 key2 返回并集

    • sunionstore destination key1 key2 将并集存储在destination中

sortedset类型

sortedset和set类型几乎一样,都是字符串的集合,都不允许出现重复的成员在同一个set中,区别在于

sortedset中每一个成员都会有一个分数(score)与之相关,

Redis中正是通过这个分数来为集合中每个成员进行从小到大排序

虽然sortedset中的成员必须是唯一的 ,但是分数score却是可以重复的

在sortedset集合中添加删除或者修改一个成员时速度较快

由于sortedset中的成员在集合中的位置是有序的,因此即便是访问位于集合中间的元素效率也是非常高的

  • zadd key score1 member1 score2 member2 score3 member3.....将所有的成员以及该成员的分数存放到sortedset集合中

  • zscore key member 返回执行成员中的分数

  • zcard key 获取集合中的成员数量

  • zrem key member[member....] 移除集合中指定的成员,可以删除多个成员

  • zrange key start end [withscores] 获取集合中脚标为start end的成员 [withscores] 参数返回成员包含的分数

  • zrevrange key start end [withscores] 按照分数从大到小的顺序返回索引从start end中间的元素 ,[withscores] 参数返回成员包含的分数

  • 删除元素

    • zremrangebyrank key start end 按照排名顺序删除从后到前的元素

    • zremrangebyscore key start end 按照分数从小到大依次删除

  • zrangebyscore key min max [withscores] [limit offset count] 返回分数在[min,max]的成员并且按照分数从小到大的进行排序 [withscores] 显示分数 [limit offset count] offset 起始值 从脚标为offset的元素开始并返回count个成员信息

  • zcount key min max 获取分数在[min,max]中间的成员个数

  • zincrby key increment member 设置指定成员的增加的分数

  • zrank key member 返回成员在集合中的排名 从小到大排序 索引从0开始的

Redis持久化

redis是一个基于内存的缓存型数据库,当redis宕机或者重启时,存储在redis中的数据就会清除

我们可以将redis内存中存储的数据进行持久化,存储到硬盘上,数据就被永久性保存在文件中。

redis的持久化机制

  • RDB机制:默认方式,不配置,redis默认就使用这种机制

    • 在一定的间隔时间内,检测key值的变化情况,然后进行持久化,把数据存储到硬盘上

    • 编辑配置redis的RDB机制 redis.conf

      • save 900 1

      • save 300 10

      • save 60 10000

    • 如果你修改了redis.conf 需要重启redis服务器

  • AOF:日志记录的方式,可以记录每一条命令的操作,可以在每一次命令操作后,进行持久化数据

    • 编辑redis.conf文件

    • 搜索 appendonly no(关闭) ----> yes

    • 搜索 appendfsync everysec

      • appendfsync everysec 每一秒进行一次持久化数据

      • appendfsync always 每一次操作进行一次持久化数据

      • appendfsync no 不进行持久化数据

    • 重启redis服务器

Java客户端连接Redis

Redis不仅可以使用命令操作,也可以使用后端开发语言进行操作 市面上主流的语言基本都支持

有很多 Java客户端,有Jedis、Redisson、Jredis等,目前企业中常用的是Jedis

开发步骤:

  • 导包:导入maven坐标依赖

<!--导入redis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.0.1</version>
</dependency>

<!--导入redis连接池依赖-->
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.3</version>
</dependency>

构建Jedis客户端对象

例如: Jedis jedis = new Jedis("192.168.68.129",6379) 主机IP地址

使用Jedis中的 API方法

代码演示:

// 练习String类型
    @Test
    public void test02() throws InterruptedException {
         // set get
        jedis.set("gender", "男");
        jedis.set("age", "20");
        String gender = jedis.get("gender");
        String age = jedis.get("age");
        System.out.println(gender);// 男
        System.out.println(age);//

        // 设置key的过期时间
        jedis.setex("gender", 5, "女");
        Thread.sleep(6000);
        String gender1 = jedis.get("gender");
        System.out.println(gender1);// null  nil



        // 增长数据
        jedis.incrBy("age", 20);
        String age1 = jedis.get("age");
        System.out.println("--------------------------------");
        System.out.println("增加数值之后:"+age1);

        // 设置多个key/value值
        System.out.println("=======================================");
        jedis.mset("address","郑州","course","Java","num","43","birthday","2020-01-01");
        List<String> mget = jedis.mget("address", "course", "num", "birthday");

        for (String s : mget) {
            System.out.println(s);
        }

        // 删除某个元素
        jedis.del("address");
        System.out.println("==========================");
        List<String> mget2 = jedis.mget("address", "course", "num", "birthday");

        for (String s : mget2) {
            System.out.println(s);
        }


    }
 // 练习Hash类型  map数据类型格式
    @Test
    public void test03() {
        // hset hget hgetall
        jedis.hset("people1", "username", "小孙");
        jedis.hset("people2", "username", "小王");
        jedis.hset("people1", "age", "20");
        jedis.hset("people1", "gender", "男");

        String username = jedis.hget("people1", "username");
        String age = jedis.hget("people1", "age");
        String gender = jedis.hget("people1", "gender");

        System.out.println("姓名:" + username + "\n" + "年龄:" + age + "\n" + "性别:" + gender);
        System.out.println("===============================================");
        String username2 = jedis.hget("people2", "username");
        System.out.println(username2);

        // 获取Hash的所有的map中的数据
        Map<String, String> people1 = jedis.hgetAll("people1");
        System.out.println("==========================================");
        System.out.println(people1);// 重写toString

        //遍历map
        // 删除
        jedis.hdel("people2", "username");
        // h获取
        Map<String, String> people2 = jedis.hgetAll("people2");
        System.out.println("====================================");
        System.out.println(people2);// {}

        System.out.println("*********************************************");
        // 获取所有的value值
        List<String> people11 = jedis.hvals("people1");
        System.out.println(people11);
        // 获取所有的key值   存放在Set集合中
        Set<String> people12 = jedis.hkeys("people1");

    }
// 练习 list类型 linkedList数据类型格式  支持重复元素
    @Test
    public void test04() {
        // lpush  头部添加元素
        // rpush  尾部添加元素
        // lpop   头部删除元素
        // rpop   尾部删除元素
        // lrange start end 获取 [start,end] 区间范围的值
        // linsert
        // 获取长度  llen("key")
        // 获取指定索引的数据  lrange("key",0,1)
        //  按照索引修改值    lset("key","0","替换的值")
        jedis.lpush("country", "美国","英国","意大利","中国");
        jedis.lset("country", 3, "中国001");
        List<String> country = jedis.lrange("country", 0, 3);
        System.out.println(country);
        // 删除区间以外的值   jedis.ltrim("key",start,end) [中国, 意大利, 英国, 中国001]
        jedis.ltrim("country", 1, 2);

        System.out.println("-------------------------------------");
        List<String> country2 = jedis.lrange("country", 0, 3);
        System.out.println("删除之后的值为:" +country2);
        // 如果内容为数字可以进行排序,不会影响原来的顺序
        jedis.lpush("agess", "20","30","10","50","100");

        List<String> ages1 = jedis.sort("agess");// [10, 20, 30, 50, 100]
        System.out.println(ages1);
        System.out.println("******************************");
        List<String> ages = jedis.lrange("agess", 0, 4);
        System.out.println("排序后的ages值为:" +  ages);// [100, 50, 10, 30, 20]

    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值