首页 > 数据库 >Redis 可以用作关系数据库吗?

Redis 可以用作关系数据库吗?

时间:2023-08-17 10:05:24浏览次数:53  
标签:OM 用作 area Spring 数据库 Redis private 关系数据库

让我们从问题“你如何使用Redis?”开始。我相信大多数人将其用作服务的缓存。但是,我希望你知道它不仅仅可以用于缓存。最近,我在一篇文章中看到一份报告,介绍了如何将部分数据迁移到Redis,并将请求首先发送到Redis。现在,我想说的是不是我们如何应用它,而是在使用Spring及其抽象时,我们可能不会立即注意到的替代情况。 让我们尝试编写一个小的Spring应用程序,它将使用两个PostgreSQL和Redis数据库。我想指出的是,我们将在数据库中存储的不是某种扁平对象,而是一个带有嵌套字段(内连接)的关系数据库的完整对象。为此,我们需要安装在Redis中的插件,例如RedisJSON和RediSearch。第一个插件允许我们以JSON格式存储对象,而第二个插件允许我们按照对象的任何字段进行搜索,甚至是嵌套字段。 为了与关系数据库一起工作,我们将选择Spring Data JPA。而为了与Redis一起工作,我们将使用出色的Redis OM Spring库,该库允许在抽象级别上与数据库进行交互。这类似于Data JPA。在底层,Redis OM Spring具有与Spring和Jedis一起使用数据库所需的所有依赖项。

先看代码

我们先开始编写代码。假设我们需要将某个实体写入数据库。在这个实体中,我添加了其他对象,例如"downtime"、"place"、"reason"等。关系数据库的实体代码如下所示:

@Entity
@Table(schema = "test", name = "downtime")
public class Downtime {

    @Id
    private String id;
    private LocalDateTime beginDate;
    private LocalDateTime endDate;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "area")
    private Place area;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "cause")
    private Cause cause;
    ...

这段代码不需要注释。我们需要为Redis做同样的事情。对象为Redis:

@Document
public class DowntimeDoc {

    @Id
    @Indexed
    private String id;
    @Indexed
    private LocalDateTime beginDate;
    private LocalDateTime endDate;
    @Indexed
    private PlaceDoc area;
    @Indexed
    private CauseDoc cause;
    ....

这种情况下,我们使用@Entity注解而不是@Document注解。这个注解表示我们的对象是一个实体,它将以“包路径+类名+Idx”的键存储在数据库中。@Entity注解表示该字段将被索引以供搜索。如果不指定此注解,那么该字段将保存在数据库中,但搜索它将返回一个空结果。您可以根据需要添加此注解。已经存在于数据库中的数据将异步进行索引;新数据将同步进行索引。接下来,我们将创建一个仓库,它主要用于从数据库中获取数据。关系数据库的示例代码如下所示:

public interface DowntimeRepository extends JpaRepository<Downtime, String> {
}

Redis的例子:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {
}

不同之处在于我们扩展了RedisDocumentRepository接口,该接口扩展了Spring的标准CRUD接口。让我们添加一个方法来查找指定原因的第一个停机时间。

public interface DowntimeRepository extends JpaRepository<Downtime, String> {

    Downtime findFirstByCauseIdOrderByBeginDate(String causeId);
}

Redis也是如此:

public interface DowntimeRedisRepository extends RedisDocumentRepository<DowntimeDoc, String> {

    DowntimeDoc findTopByCause_IdOrderByBeginDateAsc(String causeId);
}

正如你注意到的,如果通过抽象层编写与数据库交互的代码,几乎看不出差异。此外,Redis OM Spring允许使用注解自己编写查询,就像在Spring Data JPA中一样。这是一个HQL查询的示例:

@Query("SELECT d FROM Downtime d" +
        " JOIN FETCH d.area " +
        " JOIN FETCH d.cause" +
        " JOIN FETCH d.fixer" +
        " JOIN FETCH d.area.level " +
        " WHERE d.area IN ?1 AND (d.beginDate BETWEEN ?2 AND ?3 OR d.cause IN ?4) ")
List<Downtime> findAllByParams(List<Place> workPlace, LocalDateTime start, LocalDateTime end, List<Cause> causes);

Redis也一样:

@Query("(@area_id:{$areas} ) & (@beginDate:[$start $end] | @cause_id:{$causes})")
Page<DowntimeDoc> findByParams(@Param("areas") List<String> areas,
                               @Param("start") long start,
                               @Param("end") long end,
                               @Param("causes") List<String> causes, Pageable pageable);

在Redis中,我们只需指定分段的条件。不需要指定需要附加的字段,因为它们总是从数据库中获取的。但是,我们可以通过附加参数来指定我们需要的字段,而不是拉取所有字段。您还可以指定排序、限制和偏移量 - 顺便说一句,HQL中无法指定偏移量。在这个示例中,我传递了Pageable参数给方法,它将在数据库层面上工作,而不是将所有数据拉取到服务中,然后在服务中进行修剪(这与Hibernate的情况相反)。此外,Redis OM Spring还允许您使用EntityStream编写查询,它类似于Stream API。以下是使用EntityStream的上述查询的示例:

…
entityStream
        .of(DowntimeDoc.class)
        .filter(DowntimeDoc$.AREA_ID.in(filter.getWorkPlace().toArray(String[]::new)))
        .filter(between + " | " + causes)
        .map(mapper::toEntity)
        .collect(Collectors.toList());

在这个示例中,我使用了一个过滤器,使用元模型将参数作为字符串传递给第二个过滤器,以显示这两种选项都是有效的。结果是:EntityStream接受一组中间操作,并在调用终端操作时执行这组操作。

Redis OM Spring的细微差别

让我讲一些使用Redis OM Spring的细节:

  • 无法将UUID用作主键。但是可以将其指定为字符串,并对其进行索引。但是在搜索时,需要转义空格 :@id
{2e5af82m-02af-553b-7961-168878aa521е}

还有一件事:如果通过存储库进行搜索,将无法正常工作,因为代码中有一个表达式将删除所有的转义字符:RedisDocumentRepository

String regex = "(\$" + key + ")(\W+|\*|\+)(.*)";

因此,为了按这些字段搜索,需要直接在RediSearch中编写查询。我在演示项目中有一个示例,可以演示如何做到这一点。

  • 当通过方法搜索时,如果期望返回一个集合,则必须传递一个指示预期行数的参数或在@Query中指定大小;否则,将最多只能收到10条记录。
  • 该方法仅支持一个参数进行排序。可以通过编写查询来解决这个问题,使用.FT.SEARCH@Query)或.FT.AGGREGATE@Aggregation)方法。

上面的列表并不详尽。在使用这些库时,我发现了许多不同的东西,但这只是数据库实现的特定性。还有关于Redis插件的信息和讨论Redis OM Spring的所有功能。

结论

我展示了目前Redis允许存储具有大量嵌套的对象,并允许通过该对象的字段进行搜索。如果通过存储库中的抽象来处理数据,那么一些人可能看不出与Spring Data JPA的任何区别,特别是如果使用一些简单的查询,如savedeletefindAllBy等,以及通过方法名称进行查询。

作者:Artem Artemev

更多技术干货请关注wx“云原生数据库”

标签:OM,用作,area,Spring,数据库,Redis,private,关系数据库
From: https://blog.51cto.com/u_15739379/7118346

相关文章

  • CentOS8 2种方式安装redis
    方式一1、安装yuminstallredis2、编辑配置文件vim/etc/redis.conf#requirepass那行并打开注释,在后面写自己的密码,如下requirepassyourpassword将bind后127.0.0.1改为内网IP #为安全起见,请勿使用0.0.0.0protected-modeyes改为protected-modeno #关闭保护模式daemoniz......
  • Redis 实现库存扣减操作
    在日常开发中有很多地方都有类似扣减库存的操作,比如电商系统中的商品库存,抽奖系统中的奖品库存等。解决方案使用mysql数据库,使用一个字段来存储库存,每次扣减库存去更新这个字段。还是使用数据库,但是将库存分层多份存到多条记录里面,扣减库存的时候路由一下,这样子增大了并发量,但是还......
  • redis:AOF与RDB
    AOF学习自:redisAOF实现原理在Redis的配置文件redis.conf中有一节名为APPENDONLYMODE,其中有这两项:appendonly和appendfilename,是代表AOF持久化,该机制对应的文件以aof为后缀。AOF(AppendOnlyFile)持久化机制是Redis用来保证数据高可靠性和持久性的一种机制。其机制是通过将R......
  • redis配置文件:redis.conf
    配置项及说明配置项名称取值说明daemonizeyes、no是否启用守护进程(进程启动后在后台一直运行)。默认no。port Redis监听端口,默认6379bind 绑定的主机地址(只有符合条件的IP,才能用redis-cli登录该redis服务器并进行操作)bind和protected-mode控制了是否可......
  • redis的基本命令
    通用命令keyspattern查看符合要求的所有keydel(key)[key...]删除一个指定的keyexists判断key是否存在expire给一个key设置有效期,单位是秒,有效期到时该key会被自动删除(返回-2就是自动删除了)ttl查看一个key的剩余有效期help[命令]查看该命令的用法String类......
  • Redis 7的入门到精通的学习路线可以分为三个层次:入门、进阶和精通
    Redis7的入门到精通的学习路线可以分为三个层次:入门、进阶和精通学习Redis7的入门到精通的学习路线可以分为三个层次:入门、进阶和精通。下面是每个层次的学习内容和示例代码讲解。##入门阶段:1.**安装和配置Redis**:了解如何下载、安装和配置Redis的基本参数。可以使用Redis......
  • Redis 工具类
    packagecom.infinitus.opp.meeting.utils;importcom.alibaba.nacos.shaded.com.google.common.collect.Lists;importlombok.extern.slf4j.Slf4j;importorg.springframework.dao.DataAccessException;importorg.springframework.data.redis.core.RedisOperations;imp......
  • Redis入门
    1.认识NoSQL1.1 什么是NoSQLNoSQL最常见的解释是"non-relational",很多人也说它是"NotOnlySQL"NoSQL仅仅是一个概念,泛指非关系型的数据库区别于关系数据库,它们不保证关系数据的ACID特性NoSQL是一项全新的数据库革命性运动,提倡运用非关系型的数据存储,相对于铺天盖地的关系......
  • ubuntu安装redis7
    转自:https://blog.csdn.net/qwh0710/article/details/1303048611:cd/opt/2:viminstallredis7.sh,复制下面代码到编辑框。#!/bin/bashaptinstall-ysoftware-properties-commonsudoadd-apt-repositoryppa:redislabs/redissudoapt-get-yupdatesudoapt-get-yinst......
  • redis:哨兵配置文件sentinel.conf说明
    学习自:Redis——sentinel哨兵模式_sentinelannounce-ip_FlyLikeButterfly的博客-CSDN博客m:masters:slave下文中所有<xxx>项,都是可以在配置文件sentinel.conf中修改的项1、前言哨兵是从主从模式发展而来的,在m宕机的情况下,s会自动切换为m,此时原m连上后会成为新m的s。哨兵的3个......