报表无疑是ERP系统中用到的最频繁的单据之一。比如每天采购要打印采购明细帐;仓库每天要导出收货或者出货明细;销售每天要打印订单明细等。故报表的设计在ERP系统开发中占据大半江山。

不过笔者在实际工作中也发现,有些开发人员在设计ERP报表时,太过于复杂。

有一次,一家企业向我提出了如下需求,他们希望能够出一份报表,报表的内容包括四个部分:
一是成品零件的用量、零件的最小采购量等信息;
二是当月零件的采购量信息(详细的采购订单等资料);
三是当月零件的出库信息(详细的出货记录);
四是零件的安全库存信息。
然后,根据这些信息计算出当月需要补下的满足安全库存的数量。

从这个需求中可以看出,其主要设计到产品基本资料、采购、仓库等三个模块的内容。这么复杂的报表,从技术上来说,实现的难度并不是很大。但是从实用性角度考虑,或者从准确性来看,又会有什么结果呢?

一、报表越复杂,准确性越难以把握

一般来说,报表越复杂,其准确性余越难以把握。其实抛开ERP系统,从统计学的角度,我们也可以得出这个结论。如下图所示,现在有三个抽屉。每个抽屉中都有0-9十个数字。如果现在从每个抽屉中随意抽出两个数字,最后组成一个三位数。那么最后有几种结构呢?这是一个排列组合的问题。

再回过头来看一下这个表单的内容。现在这个表单有三个模块的数据构成。就好像这三个抽屉。当然其抽屉中的数据远比10个数字要负载的多。我们设想一下,从单个模块来看。可能企业允许的误差率是5%。即100条记录中,允许有5条记录与实际有偏差。现在三部分信息共同组成的一张报表,而且最后需要根据三部分信息的内容计算出一个值,那么这个出现错误的记录会有多少呢?这又是一个排列组合的问题。如假设每部分信息中,都有5条件有偏差,那么最后理论上的错误记录是125条。显然这个错误率比较大。同时也可以看出,当涉及到的基础表数量越多,涉及到的模块越多,其最后结果的准确性就越难以保障。而当数据的准确性不高时,其实用性也就相应的降低。

二、报表关联越多,其性能也会直线下降

报表越复杂,其涉及到的后台数据库基础表也就越多。虽然多表之间的关联查询是允许的,但是关联的关键字越多,其查询的效率也就越低。特别是在关联条件中,有时候采用的并不是关键字之间的关联。如有可能日期(字符数据类型的关联)之间的关联,此时查询的效率会更低。再加上比较复杂的Where逻辑判断语句,复杂报表的查询时间会很长。

如笔者测试过,按照上面这个用户的需求,设计出的报表其查询的时间需要近三分钟,而且是已经优化过的查询。

另外,这个报表的查询由于涉及到众多的基础表,数据库基本上需要访问硬盘上的数据文件,而不能够使用缓存。这就有可能会导致比较严重的硬盘I/O冲突。从而影响到其它数据的查询效率。

故从数据库与应用软件的整体性能考虑,也不建议采用比较复杂的报表视图。毕竟性能降低、查询的时间比较长时,报表的实用性也在降低。

三、设计复杂报表的注意事项

为此,从原则上是禁止设计超过两个模块的数据报表,最好是将报表的范围限制在单个模块下。如此的话,无论从性能还是从数据的准确性上都会有所保障。但是,如果用户确实有需要实现比较复杂的报表,在这种情况下,该如何处理呢?为此笔者根据自己的项目经验,提出了以下几个建议。

使用固化视图来改善数据库的性能

复杂报表所导致的不利影响,其首当其冲的是报表查询时速度会很慢,性能很低。为此在涉及到复杂报表时,开发人员可以考虑采用固化视图来改善数据库的性能。

如在Oracle数据库中,固化视图又叫做物化视图。通固化视图,可以用于预先计算并保存表连接或者聚集等耗时比较多的操作结果。简单的说,就将某个报表的查询结果存储在一张单独的表中。

如此的话,在执行查询时,就可以避免使用这些耗时的操作,同时减少磁盘的I/O冲突,从而以最短的时间得到用户想要的结果。一般来说,固化视图对于复杂的报表来说,能够提供三方面的作用。如可以提高查询的性能。如固化视图对于应用来说是透明的,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性。如当基表发生变化时,物化视图也会同时更新。

不过需要注意的是,物化视图也会带来一些负面影响。如物化视图的数据会保存在硬盘中,为此就会占用额外的存储空间等。总之,在设计比较复杂的报表时,开发人员可以与数据库工程师商量,能够采用固化视图。如果可以的话,需要尽量采用固化视图。

复杂的报表当设计到多表时,最好采用模块化的设计。

如某视图,其涉及到的基表有近20张。那么在设计视图时,要避免将其放在一个SQL语句中。而应该借鉴应用程序的模块化设计,将其设计成不同层次的视图,然后再进行连接查询。

如上面这个案例,至少可以将其分为四层。最基层是基本数据表,第二层是零件出库信息、当月采购信息等数据,第三层是根据第二层的数据进行计算分析;第三层视图再将这些视图进行连接。这么操作的话,方便后续的维护与查询。同时也可以提高查询的速度。

为什么这么说呢?如在第二层视图设计中,可以对基础表的数据进行过滤。此时由于基础数据少,那么后续的报表查询速度也会加快。为此对于比较复杂报表的设计,要考虑分层设计的思路。以提高报表的查询性能与灵活性。

要考虑数据核对的需要。

比较复杂的报表,其可能会涉及到多个不同的部门。如上面个报表,其涉及到仓库、采购、销售、开发等多个部门。而且最后的计算结果需要根据这些部门的信息得出。为此为了提高数据的准确性,就需要多个部分进行积极的配合。

那么该如何来做到这一点呢?笔者认为,可以将这些视图分模块化设计。如将涉及到不同的部门的信息先设计成不同的报表。在某个特定的时刻,如月末,先让各个部门的人员核对相关的数据。核对完成没有错误之后,再对相关的数据进行运算。而不是一开始就将所有数据在一张报表上显示。这会导致各个部门数据核对的麻烦,即各个部门不利于核对与自己相关的数据。

其实这一点跟上面提到的视图分层化设计类似。在ERP上,报表的内容也要分不同的模块进行体现。这有利于用户对数据进行核对与确认。然后再将它们整合起来。这种各个击破的方式,就有利于提高数据的准确性。

结语

可见,对于比较复杂的报表视图,原则上还是少见为妙,因为其在性能或者数据的准确性上都很难控制。

如果真的要建立复杂视图的时候,那么在设计与开发时,顾问需要听取数据库工程师的意见,或者直接使用葡萄城企业报表,这样将使你在创建这样的复杂报表时更加得心应手。

文章来源:互联网

简单三招,设计复杂ERP报表的更多相关文章

  1. mongo 固定集合,大文件存储,简单优化 + 三招解决MongoDB的磁盘IO问题

    1.固定集合 > db.createCollection(, max:});//固定集合 必须 显式创建. 设置capped为true, 集合总大小xxx字节, [集合中json个数max] { ...

  2. 信息安全系统设计基础课程实践:简单TUI游戏设计

    简单TUI游戏设计                目       录               一                      Curses库简介与基本开发方法             ...

  3. DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表

    原文:DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用 ...

  4. 【原创】IE11惊现无厘头Crash BUG(三招搞死你的IE11,并提供可重现代码)!

    前言 很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅: 分享IE7一个神奇的BUG(不是封闭 ...

  5. 【原创】三招搞死你的IE11,可重现代码下载(IE Crash keyframes iframe)!

    前言 很多人都知道我们在做FineUI控件库,而且我们也做了超过 9 年的时间,在和浏览器无数次的交往中,也发现了多个浏览器自身的BUG,并公开出来方便大家查阅: 分享IE7一个神奇的BUG(不是封闭 ...

  6. 简单的词法设计——DFA模拟程序

    实验一.简单的词法设计--DFA模拟程序 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 DFA 模 ...

  7. 学员管理系统(简单的Django设计)

    学员管理系统(简单的Django设计) 学员管理系统 项目规划阶段 项目背景 近年来老男孩教育的入学学员数量稳步快速增长,传统的excel统计管理学员信息的方式已经无法满足日渐增长的业务需求.因此公司 ...

  8. 学习LSM(Linux security module)之四:一个基于LSM的简单沙箱的设计与实现

    嗯!如题,一个简单的基于LSM的沙箱设计.环境是Linux v4.4.28.一个比较新的版本,所以在实现过程中很难找到资料,而且还有各种坑逼,所以大部分的时间都是在看源码,虽然写的很烂,但是感觉收获还 ...

  9. 云计算之路-阿里云上:消灭“黑色n秒”第三招——禁用网卡的TCP/IP Offload

    程咬金有三板斧,我们有三招.在这篇博文中我们要出第三招,同时也意味着昨天在“希望的田野”上的第二招失败了. 前两招打头(CPU)不凑效,这一招要换一个部位,但依然要坚持攻击敌人最弱(最忙最累)部位的原 ...

随机推荐

  1. ajaxsubmit 上传文件 在IE中返回的内容 提示下载文件

    在ajaxSubmit提交表单的时候,如果表单内有文件上传的话,会判断参数是否配置的iframe为false参数,如果没有,会用创建隐藏iframe方式提交表单,如果设定了iframe为false,则 ...

  2. Django两天搭建个人博客

    传送门:https://github.com/1417766861/django-blog(可直接运行,上面有步骤) 效果: 首页: 侧栏: 详情页面: 修改头像,资料,文章发布: 支持添加标签拖拽 ...

  3. 【转载】InstallShield 生成安装日志

    msiexec.exe /p "C:\Documents and Settings\qa\Desktop\8.3 Patch.msp" /l*v c:\log85gold.log ...

  4. python获取动态网站上面的动态加载的数据(初级)

    我们在处理一些网站数据的时候,有时候我们需要的数据很多都是动态加载的,而不都是静态的,以下以一个实例来介绍简单的获取动态数据,首先申明本人小白,还在学习python中,这个方法还是比较笨拙的,但是对于 ...

  5. Python学习--14 序列化

    把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等. pickle ...

  6. ADB命令获取Android UID

    有三种方案: 1. adb shell dumpsys package <packagename> | grep userId= 先通过 "adb shell dumpsys p ...

  7. docker 非root用户修改mount到容器的文件出现“Operation not permitted

    使用环境centos7 x86-64 内核版本4.19.9 docker使用非root用户启动,daemon.json配置文件内容如下: # cat daemon.json { "usern ...

  8. 30-hadoop-hbase-安装squirrel工具

    如果您的工作要求您在一天之中连接许多不同的数据库 (oracle.DB2.mysql.postgresql.Sql Server等等),或者你经常需要在多个不同种类的数据库之间进行数导入导出.那么SQ ...

  9. HBase:分布式列式NoSQL数据库

    传统的ACID数据库,可扩展性上受到了巨大的挑战.而HBase这类系统,兼具可扩展性的同时,也提出了类SQL的接口. HBase架构组成 HBase采用Master/Slave架构搭建集群,它隶属于H ...

  10. SpringMVC之文件上传

    上传是web程序中常见的功能,当使用上传时,需要把form表单中的enctype属性改为multipart/form-data,这样就使用了二进制进行上传,而后台需要解析这些数据.Dispatcher ...