zoukankan      html  css  js  c++  java
  • 报表系统结构优化之中间数据外置

           绝大多数报表项目的数据库中。除了支撑系统执行的业务数据表之外。还有非常多中间表。业务数据表是报表系统必须的基础数据表。是支持报表系统执行的持久化数据层。比如:销售报表系统中的订单、客户、产品等等。报表中间表则是计算和生成报表的中间计算过程,中间表的名字常常是五花八门。

           按道理说。业务数据表应该是大部分,报表中间表仅仅是小部分。

    可是,实际情况却恰恰相反。有些执行了较长时间的报表系统中,报表中间表达到几千个或者很多其它,而业务数据表仅仅有一两百。

    关系型数据库的综合成本是和数据表的数量、数据量相关的。数据库中存放较多的报表中间表会存在以下的问题:

           1、  表越多,数据量越大,数据库的负载压力越大,会造成性能的下降。

           2、  数据库压力达到一定程度就必须扩容,项目成本会添加不少。

           3、  数据库是扁平结构。不能以多级文件夹的形式来管理数据,仅仅适合管理数量较少的表。中间表命名任意,形成大量意义混淆的表名,可管理性变差。

           4、  表多、数据量大,会直接造成数据库管理和维护成本的添加。

           那么怎样降低报表开发中的数据库内中间表呢?分库是解决数据库内中间冗余数据的办法之中的一个,也是眼下报表项目中常见的做法。可是,无论是将数据库分成多个。还是构建专门的数据仓库。本质上还是用传统关系型数据库来承载中间数据。因此,上边所说的问题依旧存在。

           能否够将中间数据从数据库中移出来呢?小结果集直接计算后返回。大结果集放到硬盘文件上?这样做的优点很明显:

           1、减少了数据库的压力。让报表系统执行更快。

           2、  数据库不必由于报表中间表的原因扩容,减少了项目成本。

           3、  文件能够依照业务种类、模块关系、时间顺序进行多级文件夹管理,可管理性较高。

           4、  数据表少了。数据库管理和维护自然变得easy。减少了运维成本。

           可是,中间数据外置对于多数程序猿来说。仅仅是个美好的愿望而已。

    他们不是不愿意把中间表放到数据库外,而是不能放到库外。这是由于。数据一旦离开了数据库,就“失去了计算能力”。比如:某项目中有个中间表temp2009sales,是依照客户分组的2009年客户-订单数据。

    在数据库中。对这个表能够依照客户排序。

    可是一旦导出到文本文件里。文件本身是没有办法替程序猿做排序的。

     

           採用润乾集算报表。能够实现复杂计算与报表展现分离。其内置的集算引擎能够使文件拥有计算能力,实现程序猿“把报表中间数据从数据库中移出来”的愿望。引入集算报表和内置集算引擎后的报表系统结构对照方下图:


           因为集算报表支持异构的数据源,上面提到的中间temp2009sales数据文件尽管已经放到了库外,可是依旧能够和数据库中其它的业务表进行关联计算,用于终于生成报表。比例如以下图这张“某公司客户累计销售额与去年全年销售额对照报表”:


             这张报表中的客户、订单数、销售额都是直接从数据库中计算的2010年1月-10月的数据。

    2009年全年的订单数、销售额是从文件系统中的temp2009sales.b文件里读取。“销售额/去年销售额”则是今年和去年的数据共同计算的。报表上部的查询button是集算报表提供的“參数模板”功能,详细做法參见教程。这里不再赘述。这里。重点看一下这个报表的开发过程。

             首先。要提前用集算器从数据库中读取2009年等各个年份的销售数据,计算好之后,以集算器的二进制编码导出到temp2009sales.b文件里,每年一个文件。

    中间数据制作好之后,数据库中2009年的数据就能够移除备份了。不再占用数据库的空间。

             第二。编写集算器脚本salesProportion.dfx例如以下:

    注意,脚本的參数是:argyear(要查询的年份),argmonth(要查询的月份)。

           A1:连接预先配置好的数据源demo。

           A2:从数据库中计算取出要查询的年份订单数、销售额。

           A3:从前一年的数据文件里取出数据。

           A4:将A3中的数据依照A2中的CLIENT字段对齐,A2中有A3中没有的补空行。

           A5:利用A2来生成新的续表。当中添加了A4的相应行数据,比方A4(#).C:lastCOUNT就是A4的相应行(#是A2的当前行号)中取出C字段。

           A6:关闭数据库连接。

           A7:向报表返回结果集。

             第三,在集算报表中定义报表參数(argyear、argmonth)和计算数据集:

             上图中,參数名是指dfx定义的參数名称,參数值是指报表提交给集算引擎的值。这里是将报表的两个參数的值传递给集算器的同名參数。

             第四。设计报表,例如以下图:

           输入參数计算后。就可以得到前面希望的报表。


  • 相关阅读:
    Spring boot中使用log4j
    Spring Boot多数据源配置与使用
    Spring Boot中Web应用的统一异常处理
    Spring Boot中使用Redis数据库
    Spring Boot日志管理
    Spring Boot中使用@Async实现异步调用
    Spring Boot中使用@Scheduled创建定时任务
    正则表达式匹配不包含某些字符串
    Spring Boot中使用JdbcTemplate访问数据库
    Selenium2学习-024-WebUI自动化实战实例-022-网站不同分辨率下页面样式展示兼容性问题解决方案 -- 设置浏览器显示区域大小(无人值守,节约测试成本的福音,BOSS 最爱)
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5337215.html
Copyright © 2011-2022 走看看