报表工具应对非关系数据库数据源的方法

报表工具连接 RDB 可以使用通用的 JDBC/ODBC,几乎所有报表工具都提供了相应支持,但对于非 RDB 各类报表工具的能力就不尽相同了。本文探讨报表工具应对非 RDB 的常用方法并点评,我们将从以下几个方面对这些方法进行考察:

1. 是否能连接数据源取数
2. 是否能利用原生数据源的计算能力,充分发挥数据源优势
3. 是否拥有独立计算能力,当数据源计算能力不足时有足够能力处理数据,避免将计算都压到报表工具中(报表工具计算能力也有限)
4. 是否支持大数据,报表工具往往不具备大数据量处理能力

常见的非 RDB 数据源包括但不限于:

  • File&API。Txt/Csv、Excel、Json、Xml、HDFS、Ftp
  • Big data&NoSQL。MongoDB、Cassandra、HBase、Redis、Hive、Spark、Elasticsearch、Kafka
  • 多维数据库。Essbase、SSAS
  • 时序数据库。InfluxDB
  • ERP&CRM。Salesforce、SAP
  • Webservice

报表工具支持

一款报表工具本身会支持一些数据源,其中就包括非 RDB 数据源。绝大部分报表工具支持 Csv 和 Excel,Json 其次,另外有些工具也提供 MongoDB、Webservice 支持。如开源的 BIRT 和 JasperReports 支持 Csv、XML、Excel 等文件数据源,可以访问 MongoDB 取数,还能对接 Webservice,可以应付一些常见场景。

使用报表工具提供的数据源功能会相对快捷,不需要额外做过多配置。不过,由于非 RDB 数据源的特殊性,各类报表工具支持的方式也不尽相同,有的通过可视化界面即可完成数据集创建,这种方式虽然简单但不够灵活,有的则需要编写脚本,有一定灵活性但使用难度又大幅增加,缺乏简单通用的方式来应付这类数据源。

是否能利用原生数据源的计算能力要看报表工具对数据源的支持方式,有些报表工具仅提供字段选取和条件过滤进行数据读取,如果要对数据进一步加工要通过不同数据集再运算(如 JOIN),没法利用数据源自身的计算能力(如 MongoDB 中的 $lookup 操作),而数据源端计算往往更高效,计算后的结果也可能更小,提升传输效率也更快。显然,报表工具在这方面表现并不理想。

对于独立计算能力,有些报表工具在数据集(数据准备)阶段提供了关联运算和脚本计算,但功能都比较简单,如果要进行更复杂的计算要借助自定义接口实现,这又跟报表工具自身的能力无关了。

大数据支持方面,绝大多数报表工具都采用全内存方式进行数据加载和结果呈现,所以大数据量情况下内存消耗更多,性能也很差。

非官方 JDBC

报表工具一般都天然支持 JDBC 数据源,对于一些官方没有提供 JDBC 的特殊数据源,有时第三方会自行开发并发布使用,这样报表工具就可以很方便地连接数据源了。需要注意的是,这类 JDBC 往往由个人开发,质量参差不齐,好用与否经常靠运气,整体不够稳定。

以下几个 JDBC 供参考:

elasticsearch-jdbc:https://github.com/jprante/elasticsearch-jdbc

salesforce-jdbc:https://github.com/ascendix/salesforce-jdbc

influxdb-java:https://github.com/influxdata/influxdb-java

这类 JDBC 往往仅提供取数功能,进一步运算还需要继续在报表端完成。因此我们考察的后三点能力基本都没有。

数据源连接器

数据源连接器(DataSource Connector)是一种专门用于应用程序连接数据源的工具。对于非 RDB 数据源,优秀的连接器不仅可以实现连接,还可以提供一定的 SQL 支持以方便应用开发人员快速读取数据。CData Connector 就是其中一种。

CData 目前提供了 225 种数据源连接支持,可以涵盖绝大部分常用的数据源(但不支持 influxdb)。连接器支持 JDBC、ODBC、ADO.NET 以及 Python 可以适应不同的应用场景。

CData 连接器宣称针对大部分数据源提供了 SQL-92 支持,报表工具可以通过 SQL 访问数据,无论数据源是 Excel 还是 MongoDB。但实际使用时对复杂计算的支持并不好,计算能力较弱。

使用 CData JDBC 连接器需要下载指定数据源的 jar,报表工具引入 jar 配置数据源即可连接。如 Excel 的连接信息如下:

JDBC Driver:cdata.jdbc.excel.ExcelDriver

JDBC URL:jdbc:excel:Excel File='D:/documents/orders.xlsx'

使用 SQL 读取时会以 Excel 中的 sheet 名作为表名,如:

SELECT * FROM Sheet1

其他数据源也可以采用类似的方式进行连接,用户可以选择 CData 为每种数据源提供的对应的连接器,也可以使用 all-in-one 连接器。

数据源连接器可以比较方便地用于报表工具应对纷繁复杂的非 RDB 数据源,提供的 SQL 支持可以完成大部分相对简单的数据准备工作。需要注意,在应用和数据源之间添加数据源连接器是否会影响影响性能要做针对性测试,这方面在诸如 CData 的官方文档中并没有详细提及。

数据源连接器往往具备一定的计算能力(SQL 支持),但对复杂计算支持不足,本身 SQL 处理复杂计算就很吃力(尤其缺乏窗口函数时),而数据源连接器对 SQL 支持又不完整,计算能力不足也是自然而然的了。

数据源连接器也基本不具备大数据处理能力,虽然大部分数据源连接器都提供 SQL 支持,但却很难使用类似的数据库分页机制(虽然数据库分页也有问题)。不仅如此,大数据计算场景下往往还要依赖专门的大数据计算技术(如并行与外存计算),这些都是数据源连接器无法提供的。

自定义扩展接口

很多报表工具都预留了数据源(数据集)扩展接口(脚本数据集或自定义数据集)以方便用户编写自定义程序完成特殊情况下的数据源连接和数据处理。

自定义数据源时经常会借助专门的计算库完成数据源连接和数据准备工作。如处理 Excel 使用的 POI,处理 XML 的 dom4j,处理 Json 的 JsonPath,处理 CSV 的 CSVJDBC,MongoDB 的 Connector,以及 dataFrame 类函数库(Tablesaw/ Joinery/ Morpheus/ Datavec/ Paleo/ Guava)等。使用这些计算库可以极大加快数据源连接与处理速度。

与数据源连接器不同,计算库通常具备很强的计算能力,可以胜任更复杂的报表数据准备工作,即使计算库的能力有限,在自定义数据源中用户还可以通过编码进一步扩展,灵活性大大增强。

自定义数据源可以通过编码充分利用数据源自身的计算能力,借助计算库和编码也能完成复杂数据计算,同时也可以进一步应付大数据场景,理论上来讲,没有什么问题是硬编码解决不了的。但反过来,这种方式由于需要大量编码导致使用难度大幅增加,实际业务中往往只在一些比较个性化的场景下使用。

集算器 SPL

集算器是专业的开源数据处理引擎,除了提供多种数据源连接外,其本身具备很强的计算能力,相当于数据源连接器和计算包的合体。集算器提供了独立的脚本语法 SPL,使用 SPL 可以很方便连接非 RDB 数据源,完成数据计算。集算器提供了标准 JDBC 和 ODBC 接口供报表工具调用 SPL 的计算结果。

如连接 MongoDB 并完成关联运算的 SPL 脚本(mongo.dfx)如下:

A
1 =mongo_open("mongodb://127.0.0.1:27017/mongo")
2 =mongo_shell(A1,"test1.find()")
3 =A2.new(Orders.OrderID,Orders.Client,Name,Gender,Dept).fetch()
4 =mongo_close(A1)
5 return A3

在报表工具建立 JDBC 数据源,集算器 JDBC 连接如下:

JDBC Driver:com.esproc.jdbc.InternalDriver

JDBC URL:jdbc:esproc:local://

在报表数据集中通过类似访问存储过程的方式调用 SPL 脚本,完成 MongoDB 连接与数据处理,如:

call mongo()

其中,mongo 为上述 SPL 脚本名称(mongo.dfx)。

除了 SPL 原生语法,集算器还支持 SQL 语法。如针对 MongoDB 的 2 个单层 collection 关联:

A
1 =mongo_open("mongodb://127.0.0.1:27017/mongo")
2 =mongo_shell(A1,"Orders.find()").fetch()
3 =mongo_shell(A1,"Orders.find()").fetch()
4 =mongo_close(A1)
5 $select   o.OrderId,o.Client,e.Name,e.Gender,e.Dept from {A2} o join {A3} e on   o.SellerId=e.EId

SPL 对接非 RDB 数据源大多采用 CLI 接口方式,可以充分利用原生数据源的计算能力。如支持 MongoDB 的 json 查询表达式(find、count、distinct 和 aggregate),这样区间查询可以写作:

=mongo_shell(A2,“test1.find({Orders.Amount:{$gt:1000,$lt:3000}})”)。

同时 SPL 还拥有大数据计算能力,有序运算、外存计算、并行计算等可以应对绝大部分大数据场景,为报表工具快速输出结果集。

在数据源支持方面,集算器 SPL 支持的数据源有几十种,绝大部分场景已经够用。支持的部分典型数据源列举如下:

  • 阿里云
  • Cassandra
  • 多维数据库
  • ElasticSearch
  • Ftp
  • Hbase
  • Hdfs
  • Hive
  • Influxdb
  • Informix
  • Kafka
  • MongoDB
  • Redis
  • Salesforce
  • Sap
  • Spark
  • Webcrawl
  • Webservice
  • YModel
  • Zip

综合比较来看,各类报表工具对非 RDB 数据源的支持程度不同,有的数据源即使支持功能也很简单,这就导致面对一些数据源或一些场景时必须依靠其他方式进行访问。非官方的 JDBC 本身不够稳定自然不是应对多样性数据源的首选。数据源连接器虽然方便但数据处理能力较弱,有的连接器也不够稳定。自定义数据源理论上什么都能满足,但实施复杂度过高,不到万不得已通常不会使用。集算器 SPL 表现相对良好,可以应对常见的多样性数据源情况(虽然数据源种类还不够多,但大部分情况够用),同时具备较强的数据处理能力,支持大数据计算,可以满足特殊场景的需要,相当于以上几种方式的合集。