报表工具应对多步骤数据准备的方法
有些报表的运算比较复杂,从原始数据到呈现需要经过多步加工,如何更简单高效地实现复杂多步骤的运算直接影响到报表开发效率和性能。本文将比较几种常见的报表多步骤数据准备的方法。
复杂 SQL/ 存储过程
RDB 数据源具备较强的计算能力,使用 SQL 可以完成大部分数据处理任务,不过复杂 SQL 的编写难度较高,往往需要专业的 DBA 而非报表开发人员才能搞定。而有些多步运算一句 SQL 很难完成,这时对于支持存储过程(简称 SP)的数据库还可以编写 SP 来应对多步复杂运算。
不过,SP 的缺点也很明显。SP 与数据库一同存放导致报表与数据库紧耦合维护困难,报表经常变化就要经常操作数据库改 SP,这同时会带来安全问题。SP 几乎没有移植性,通用性差,无论是拆分扩展数据库还是更换数据库类型,SP 都将失效。
即使如此,也并不是所有数据库都支持 SP,像 Vertica 只能通过调用外部程序(UDF)变相实现 SP 的功能,其复杂度又要高很多。而其他非 RDB 数据源,如 NoSQL、File、Webservice 本身连 SQL 都不支持或支持的不好(有一些文件 SQL 引擎)就更别提 SP 了。不支持 SP,应对报表中的复杂多步骤数据准备就更吃力了。
自定义数据集
很多报表工具还会提供自定义数据准备接口,将数据准备的工作完全交由用户自定义程序完成,毕竟没有什么计算是硬编码搞不定的。这种方式用户的自由度很高,但难度也最大,即使使用一些专门的计算类库也需要专业的程序员而非报表开发人员才能搞定。
除了开发难度,自定义数据准备程序(如 Java)往往又要和主程序一起编译部署导致报表模块与主应用紧耦合不利于模块独立与维护。而报表多变修改自定义程序又会导致应用重启,这显然对系统运行和维护十分不利。
报表工具辅助格
一些网格类报表工具(控件类很难实现)还可以借助辅助格进行数据准备。实现时会增加一些单元格,通过位置关系和变量完成中间步骤的数据计算,然后再将这些单元格隐藏从而实现多步运算。
不过这种方式能够完成的计算十分有限,本身报表呈现模板的主要目标是数据呈现而非数据运算,计算能力并非强项。此外,大量使用辅助格会大量消耗内存影响报表运行性能。辅助格也不利于报表维护,过多使用会破坏原本清晰的格间关系(状态式)导致报表混乱。总体来讲,这是一种非常规报表数据处理形式,实际中不应过于依赖。
集算器 SPL
集算器是专业的开源数据处理引擎,可以用于完成报表数据复杂多步的准备工作。其位置介于报表和数据源之间,但更贴近报表端,可以与报表集成使用。这样报表工具就拥有了复杂多步数据准备的能力,既不与数据源耦合,也跟主应用独立。集算器提供了标准 JDBC 和 ODBC 接口供报表工具调用 SPL(集算器的形式化脚本语言)的计算结果。
在计算实现简洁性上,SPL 也颇具优势,下面是一个例子:
根据股票记录表查询股价连续上涨超过 5 天的股票及上涨天数(股价相等记为上涨)
SQL 实现:
select code,max(risenum)-1 maxRiseDays from
( select code,count(1) risenum from
(
select code,changeSign,sum(changeSign) over(partition by code order by ddate) unRiseDays from
(
select
code,
ddate,
case when price>=lag(price) over(partition by code order by ddate)
then 0 else 1 end changeSign
from stock_record
)
)
group by code,unRiseDays
)
group by code
having max(risenum) > 5
SPL 实现:
A |
||
1 |
=connect@l("orcl").query@x("select * from stock_record order by ddate") |
|
2 |
=A1.group(code) |
|
3 |
=A2.new(code,~.group@i(price<price[-1]).max(~.len())-1:maxrisedays) |
计算每只股票的连续上涨天数 |
4 |
=A3.select(maxrisedays>=5) |
选出符合条件的记录 |
可以看到 SPL 支持分步计算,可以按照自然解题思路分步实现算法,而 SQL 则要组合成冗长嵌套的一句才能实现。
同时 SPL 还拥有大数据计算能力,有序运算、外存计算、并行计算等可以应对绝大部分大数据场景,为报表工具快速输出结果集。
综合来看,自定义程序的方式最灵活但复杂度也最高应用并不容易,还可能产生应用间的耦合性问题;SQL/SP 实现复杂多步运算难度稍低(也很复杂)但数据源适用范围有限,还容易产生数据库方面的各种问题。报表工具自身的辅助格方式能力十分有限,难以应付复杂计算场景。由此看来,这三种方式并不是报表应对复杂多步数据准备的首选。集算器 SPL 实现难度低,灵活性也与自定义程序相当;工程上其结构也更合理。从 SP 的角度看 SPL 更像一种脱离数据库的库外存储过程,从自定义程序角度来看,SPL 更像一种低耦合、低复杂度的自定义程序实现。