为什么会有这么多中间表?

imagepng

中间表的由来

中间表是数据库中专门存放中间计算结果的数据表。报表系统中的中间表是普遍存在的。那么,这些中间表是如何出现的?为什么中间表会越来越多?中间表会给项目组带来什么样的困扰,如何解决这些困扰?这里我们就尝试探讨一下这个问题。

中间表出现的典型场景主要有三个:

  1. 一步算不出来。数据库中的原始数据表要经过复杂计算,才能在报表上展现出来。一个 SQL 很难实现这样的复杂计算。要连续多个 SQL 实现,前面的生成中间表给后边的 SQL 使用。
  2. 实时计算等待时间过长。因为数据量大或者计算复杂,报表用户等待时间太长。所以要每天晚上跑批量任务,把数据计算好之后存入中间表。报表用户基于中间表查询就会快很多。
  3. 多样性数据源参加计算。来自于文件、NOSQL、Web service 等的外部数据,需要与数据库内数据进行混合计算时,传统办法只能导入数据库形成中间表。

中间表带来的问题

在一个运营商的报表系统中,我们发现了一个让人吃惊的现象。在 DB2 数据仓库中,有两万多个数据库表!经过深入了解发现,真正的原始数据表只有几百张,剩下的大量的数据库表都是为查询和报表服务的中间表。

经过几年乃至十几年的运行,数据库中的中间表越来越多,甚至出现这个项目中上万个的情况。大量中间表带来的直接困扰是数据库存储空间不够用,面临频繁的扩容需求。中间表对应的存储过程、触发器等等需要占用数据库的计算资源,也会造成数据库的扩容压力。

那么,是不是可以清理掉一些不用的中间表?一般的结论都是:搞不动。数据库中的中间表是不同程序员制作的,有的是综合查询系统使用,有的是报表系统使用。中间表之间还存在交叉引用,有些程序员看到有别人生成的中间表就直接使用了。有时候一些查询报表已经废弃不用了,但是对应的中间表没人敢删,因为不知道删掉之后会影响其他什么查询或者报表。

很多情况下,项目组只好为了越来越多的中间表去扩容数据库。但是数据库的扩容成本太昂贵了:不管是换更强的服务器(纵向扩容),还是增加数据库服务器的节点(横向扩容),都不便宜。过于频繁的扩容让项目组非常头疼。

那么,能不能把中间表导出到文件中,从而减轻数据库的压力呢?这个办法初看挺好,但是有个问题始终无法解决。例如:每天晚上把经营分析表数据生成好之后放到文件中,第二天上班的时候发现,业务人员还要对经营分析表按照各种条件过滤,或者按照各种维度分组。因为文件本身是没有计算能力的,一旦把中间表从数据库中导出成文件就很难进一步计算了。不得已,只能把中间表继续留在数据库中。

解决问题的办法

采用润乾集算器实现文件计算,就可以把中间表从库中迁移到文件系统中了。采用集算器的前后对比图如下:

集算器结构示意图1

在集算器结构中,数据库的大量中间表都移到了库外,数据库仅仅存储少量原始数据表,压力就小了很多。针对这些中间表实现的多个 ETL 存储过程、触发器、复杂 SQL 也都由集算器来实现,数据库的计算压力也变小了很多。虽然计算和存储压力由应用服务器来承担,但是成本还是要比数据库服务器低很多。项目组不用再每隔一段时间就申请数据库服务器扩容了。

同时,集算器可以读取多样性数据源,直接参与混合计算。无需再导入数据库,成为中间表。

集算器编程很容易

移到库外的数据文件不能再使用 SQL 计算了,换成集算器会不会增加编写的难度呢?实际上,集算器编写简单计算脚本的时候和 SQL 差不多,复杂多步骤计算还要比 SQL 容易。例如:

  • 读取文件
A
1 =file(“D:/report/HR/employee.b”)
2 =A1.import@b()
  • 实现过滤
A B
1 =file(“Order_Books.b”).import@b() =A1.select(Amount>=20000 && month(Date)==3)
  • 分组汇总
A B
1 =file(“Order_Books.b”).import@b() =A1.select(Amount>20000)
2 =A1.groups(SalesID, month(Date); sum(Amount), count(~))

从上述例子来看,采用集算器实现数据文件库外计算,学习成本很低,很容易掌握。

新方案的价值

新方案的价值还不仅仅是降低数据库的压力。

对于报表应用而言,中间数据的存在是有价值的:有些中间表是报表业务决定的,有些是为了弥补现有技术的不足。也就是说,中间数据和报表模板一样,都是报表系统的一部分。所以,集算器的方案并没有让中间数据消失,只是移到了库外,保存在报表应用的文件目录中,使得中间表在物理上也成为了报表应用系统的一部分。这样既能发挥中间数据的价值,还可以让中间数据和报表系统的其他部分一起管理。显然,文件系统的树形目录结构比数据库混在一起的几万个表要更容易维护。

在实际项目中,可以给中间数据文件建立多层文件夹存储。例如:第一层目录是财务管理、人力资源、ERP 等等。人力资源又有子目录:工资管理,基本信息,党员信息等等。目录可以细化到某个报表,如果该报表发生了变化,只需要调整这个目录中的报表模板或者数据文件即可。如果该报表废弃不用,那么删掉或者移走报表所在目录,就可以快速的释放硬盘空间。

从计算速度来说,由于文件更底层,更接近于磁盘,IO 性能要好于数据库。所以集算器的方案可以为报表系统带来更快的性能。

报表数据来自于多样性数据源时,还可以有更好的实时性,不像传统手段时只能定期入库。