一个 SQL 查询访问 Java 中的多个数据源(来自 oracle、excel、sql 服务器)

One SQL query to access multiple data sources in Java (from oracle, excel, sql server)

我需要开发可以使用一个 SQL query 从多个数据源(Oracle, Excel, Microsoft Sql Server 等)获取数据的应用程序。例如:

 SELECT o.employeeId, count(o.orderId) 
    FROM employees@excel e. customers@microsoftsql c, orders@oracle o 
    WHERE o.employeeId = e.employeeId and o.customerId = c.customerId 
    GROUP BY o.employeeId;

此 sql 和数据源必须由 java 程序动态更改。 我的客户想在我的应用程序的 Web 界面中同时从不同的数据库和存储写入 运行 sql-like query group by, having, count, sum 等等。其他要求是性能和重量轻。

我找到了这种方法(以及我看到的缺点,如果我错了,请修复我):

  1. Apache Spark缺点:繁重的解决方案,对BigData更好, 如果您需要在不缓存的情况下获取最新信息,则速度较慢 在 Spark 中),

  2. SQL服务器中的分布式查询(Database link of Oracle链接 Microsoft SQL Server, Power Query of Excel) 的服务器 - 缺点: 通过 java 程序动态更改数据源的问题和 使用 Excel、

  3. 时出现问题
  4. Prestodb缺点:重解决方案,对大数据更好),

  5. Apache Drill缺点:相当年轻的解决方案,有些问题没有 最新的 odbc 驱动程序和一些工作时的错误),

  6. Apache Calcite(Apache Drill 使用的轻型框架, 缺点:还很年轻的解决方案),

  7. 手动从数据源加入(缺点:需要做很多工作 制定正确的连接,结果集中"group by",找到最佳执行计划等)

可能是,您是否知道任何其他方式(使用免费开源解决方案)或根据您的经验给我关于上述方式的任何建议?任何帮助将不胜感激。

SQL与数据库管理系统有关。 SQL 服务器将需要除 Oracle SQL 服务器之外的其他 SQL 语句。

我的建议是使用JPA。它完全独立于您的数据库管理系统,使 Java 中的开发更加高效。

缺点是,不能将多个数据库系统与开箱即用的 JPA 组合在一起(就像 SQL 服务器和 Oracle SQL 服务器之间的 1:1 关系)。但是,您可以在代码中创建多个 EntityManagerFactories(每个数据库一个)和 link。

JPA 在这种情况下的优点:

  • 编写数据库管理系统独立的 JPQL 查询
  • 减少所需的java代码

JPA 的缺点:

  • 您不能关联来自不同数据库的实体(例如 1:1 关系)
  • 你不能用一个查询查询多个数据库(将来自不同数据库的表组合成 group by 或类似的)

更多信息:

可能是工资观念。尝试使用 Apache solr。使用不同的数据源并将数据导入 Apache solr。一旦数据可用,您就可以通过索引编写不同的查询。

它是开源搜索平台,确保您的搜索速度更快。

UnityJDBC 是一个 商业 JDBC 驱动程序,它包装了多个数据源并允许您将它们视为同一个数据库的一部分。它的工作原理如下:

您定义了一个“架构文件”来描述您的每个数据库。架构文件类似于:

...
<TABLE>
    <semanticTableName>Database1.MY_TABLE</semanticTableName>
    <tableName>MY_TABLE</tableName>
    <numTuples>2000</numTuples>
 <FIELD>
    <semanticFieldName>MY_TABLE.MY_ID</semanticFieldName>
    <fieldName>MY_ID</fieldName>
    <dataType>3</dataType>
    <dataTypeName>DECIMAL</dataTypeName>
    ...

您还有一个中央“源文件”,它引用您所有的架构文件并提供连接信息,它看起来像这样:

<SOURCES>
    <DATABASE>
        <URL>jdbc:oracle:thin:@localhost:1521:xe</URL>
        <USER>scott</USER>
        <PASSWORD>tiger</PASSWORD>
        <DRIVER>oracle.jdbc.driver.OracleDriver</DRIVER>
        <SCHEMA>MyOracleSchema.xml</SCHEMA>
    </DATABASE>
    <DATABASE>
        <URL>jdbc:sqlserver://localhost:1433</URL>
        <USER>sa</USER>
        <PASSWORD>Password123</PASSWORD>
        <DRIVER>com.microsoft.sqlserver.jdbc.SQLServerDriver</DRIVER>
        <SCHEMA>MySQLServerSchema.xml</SCHEMA>
    </DATABASE> 
</SOURCES>

然后您可以使用 unity.jdbc.UnityDriver 允许您的 Java 代码连接到 运行 SQL 跨数据库,像这样:

String sql = "SELECT *\n" +
"FROM MyOracleDB.Whatever, MySQLServerDB.Something\n" +
"WHERE MyOracleDB.Whatever.whatever_id = MySQLServerDB.Something.whatever_id";
stmt.execute(sql);

所以看起来 UnityJDBC 提供了您需要的功能,但是,我不得不说,任何允许用户执行任意连接表 SQL 的解决方案 跨不同的数据库 听起来像是让你的数据库崩溃的秘诀。我实际上会根据您的要求类型推荐的解决方案是 do ETL processes from all of your data sources into a single data warehouse 并允许您的用户查询;如何定义这些流程和您的数据仓库对于 Whosebug 问题来说绝对太宽泛了。

合适的解决方案之一是 DataNucleus 具有 JDO、JPA 和 REST API 的平台。它支持几乎所有 RDBMS(PostgreSQL、MySQL、SQLServer、Oracle、DB2 等)和 NoSQL 数据存储,例如基于地图、基于图形、基于文档等、数据库 Web 服务、LDAP、XLS、ODF 等文档,XML等

您也可以使用 EclipseLink,它也支持 RDBMS、NoSQL、数据库 Web 服务和 XML。

By using JDOQL which is part of JDO API, the requirement of having one query to access multiple datastore will be met. Both the solutions are open-source, relatively lightweight and performant.

我为什么建议这个解决方案?

  • 根据您的要求,我们了解到数据存储将是您的客户选择,您并不是在寻找大数据解决方案。
  • 您更喜欢 open-source 解决方案,它们重量轻且性能高。
  • 考虑到您的用例,您可能需要一个具有多语言持久性行为的数据管理平台,它能够利用多个数据存储,基于 your/customer 的用例。

To read more about polyglot persistence

https://dzone.com/articles/polyglot-persistence-future

https://www.mapr.com/products/polyglot-persistence

这就是 Hibernate 框架的原因,Hibernate 有自己的查询语言 HQL,大部分与 SQL 相同。 Hibernate 充当中间件,将 HQL 查询转换为特定于数据库的查询。

有一些候选人(Apache Spark、Prestodb、Apache Drill)的经验让我选择了 Prestodb。尽管它主要用于大数据,但我认为它很容易设置,并且它支持(几乎)你所要求的一切。网上有很多资源(包括 运行 它在 Docker) and it also has excellent documentation 和活跃的社区,还有两家公司(Facebook 和 Netflix)的支持。

我会推荐 prestocalcite性能轻量级并不总是齐头并进。

  • presto :正如您所说 "big data",已经有很多经过验证的用法。表现良好。我不太清楚轻量级具体是什么意思,如果需要更少的机器是其中之一,你绝对可以根据需要减少规模

  • calcite :嵌入了许多数据分析库,如 drill kylin phoenix。做你需要的“连接到多个数据库”,最重要的是 "light weight"

来自不同供应商的多个服务器上的多个数据库 最具挑战性的情况是当数据库位于不同的服务器上并且某些服务器 运行 不同的数据库软件时。例如,客户数据库可能托管在 Oracle 的机器 X 上,而订单数据库可能托管在装有 Microsoft SQL 服务器的机器 Y 上。即使两个数据库都托管在机器 X 上,但一个在 Oracle 上,另一个在 Microsoft SQL 服务器上,问题是相同的:这些数据库中的信息必须以某种方式在不同平台之间共享。许多商业数据库使用某种形式的联合、集成组件或 table linking(例如 IBM、Oracle、Microsoft)支持此功能,但支持开源数据库(HSQL, MySQL, PostgreSQL) 有限。

有多种方法可以解决这个问题:

  • Table Linking and Federation - link tables 从一个来源变成 另一个用于查询
  • Custom Code - 编写代码和多个查询手动组合 数据
  • Data Warehousing/ETL - 将数据提取、转换和加载到 另一个来源
  • Mediation Software - 编写一个由翻译人员翻译的查询 调解员提取所需数据