一个用Java访问多个数据源的SQL查询(来自oracle,excel,sql server)

Via*_*nin 14 java sql oracle apache-spark-sql apache-drill

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

 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;
Run Code Online (Sandbox Code Playgroud)

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

我找到了这种方式(我看到了什么缺点,如果我错了,请修理我):

  1. Apache Spark(缺点:重型解决方案,对于BigData更好,如果你需要获取最新的信息而不在Spark中缓存它,则会很慢),

  2. 在SQL Server分布式查询(甲骨文的数据库链接,微软SQL服务器的链接服务器,Excel的电源查询) - 缺点:与Excel的工作问题,通过动态java程序和问题变化的数据源,

  3. Prestodb(缺点:重型解决方案,对BigData更好),

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

  5. Apache Calcite(Apache Drill使用的ligth框架, 缺点:非常年轻的解决方案),

  6. 手动从数据源加入(缺点:开发正确连接的很多工作,在结果集中"分组",找到最佳执行计划等)

也许,你知道其他任何方式(使用免费的开源解决方案)或者从你对上述方法的经验中给出任何建议吗?任何帮助将不胜感激.

hee*_*nee 7

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>
    ...
Run Code Online (Sandbox Code Playgroud)

您还有一个中央" 源文件 ",它引用所有模式文件并提供连接信息,它看起来像这样:

<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>
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用unity.jdbc.UnityDriverJava代码来运行跨数据库连接的SQL,如下所示:

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

因此看起来UnityJDBC提供了您所需的功能,但是,我必须说任何允许用户执行任意SQL的解决方案,这些SQL将表连接到不同的数据库听起来像是让您的数据库瘫痪的秘诀.我真的建议你的类型的要求,解决的办法是ETL所有的数据源的过程到一个单一的数据仓库,并允许用户来查询; 如何定义这些进程和数据仓库对于stackoverflow问题来说肯定太宽泛了.

  • 我同意.这要求数据仓库保留所有信息. (3认同)

Har*_*ari 4

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

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

通过使用属于 JDO API 一部分的 JDOQL,可以满足一个查询访问多个数据存储的要求。这两种解决方案都是开源的、相对轻量级且高性能。

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

  • 从您的要求来看,数据存储将是您的客户选择,您并不是在寻找大数据解决方案。
  • 您更喜欢轻量且高性能的开源解决方案。
  • 考虑到您的用例,您可能需要一个具有多语言持久性行为的数据管理平台,该平台能够根据您/客户的用例利用多个数据存储。

阅读有关多语言持久性的更多信息

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

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