精华内容
下载资源
问答
  • 2020-09-06 19:52:41

    MicroStrategy报表开发流程

    前言

    最近接手的报表项目衍生的MicroStrategy初步开发流程,记录整体流程开发步骤,以防以后遗忘,会随着经验的累计而更新(大概)。

    开发流程

    1.前置

    在项目开始之前,MSTR有几步很关键的前置需要确认,否则可能连启动项目源都无法顺利执行。

    确认Server

    通常情况直接在客户方开发时客户方服务器会提前准备好相关的环境(创建项目源等),但自己使用时需要提前确认相关项是否存在问题,以防后续开发工作不能顺利进行。

    首先打开MicroStrategy Developer,Developer目前使用后初步定义为MSTR的主要编辑/开发场景,通过Developer对项目对应的项目源进行连接,连接时需要输入账号以及密码。

    MicroStrategy Intelligence Server可以通过Service Manager管理。

    若存在MSTR项目源无法启动,可通过日志文件查看具体原因所在,日志文件路径根据配置决定,文件名为DSSErrors.log

    推测默认安装在
    盘符:\Program Files (x86)\Common Files\MicroStrategy\Log
    
    判断日志文件可以根据文件最新的修改时间来确认。
    

    报表项目初步开始时发现项目源已经创建,但无法启动相应服务,因此查看日志信息,获取以下信息。

    --服务器未启动
    [Error][0x80043705] 连接失败。可能的原因是 a)服务器不在运行 b)服务器正在载入项目 c)网络问题 d)服务器达到的连接数限制
    
    --服务未激活
    [Fatal] Intelligence Server因为没有激活所以不能启动。请通过License Manager或者通过访问在https://licensing.microstrategy.com的激活网站来激活你的安装。
    

    确认为激活问题,与客户方沟通后解决。

    确认服务

    MSTR在启动后会有一条叫做MicroStrategy Intelligence Server的服务需要手动启动(可能根据客户的设置来决定是手动/自动)。

    --怎么打开服务?
    开始菜单---->搜索框---->搜索'服务'---->齿轮图标的就是
    

    项目初期我并没有启动成功,根据日志文件推测是客户方还未激活其测试机器上的Server,与客户方反馈后解决了该问题。

    确认项目源

    推测项目源基于Intelligence Server进行连接,Server不启动项目源也无法连接,如果两者都并未存在,则可能需要自己手动创建新项目源。

    2.连接/创建项目

    一个项目源底下可以有多个项目,在Developer中定义的MSTR对象隶属于项目。
    Developer自带项目生成向导,选项栏:框架---->创建新项目,然后根据向导进行创建,创建过程并无太大难度。

    3.创建数据库实例

    数据库实例基于数据源建立,而数据源需要通过MicroStrategy Connectivity Wizard进行配置,所以在创建数据库实例之前需要先通过MicroStrategy Connectivity Wizard配置连接信息。

    --MicroStrategy Connectivity Wizard所在位置
    开始菜单---->MicroStrategy Tools---->connectivity Wizard
    
    --具体配置信息
    目标数据库类型
    目标数据库地址
    目标数据库账号密码
    ····(与通常连接数据库填写的相关项相似)
    

    数据源连接配置成功后,可以进行相关的数据库实例创建。

    数据库实例位置:项目源—>管理—>配置管理器—>数据库实例,右键即可直接新建。

    4.表格获取

    数据库实例建立成功以后,还需要将本次报表开发相关的表导入项目,才能在后面的对象中被引用。

    进入到对应的项目下,在工具栏选择:框架---->数据仓库(确认一下有没有开只读模式)。

    然后就选择自己创建的数据库实例,将数据库中报表关联的数据表从左边移到右边,确认后点击保存并关闭,然后选择图标一栏最右边的更新框架。

    5.创建实体

    创建实体需要也需要根据实际的业务需求来决定,本次项目中并未需求多张表的同一字段/度量,所以创建过程相对简单。

    1.在创建好的实体文件夹下,右键--->新建--->实体
    2.这时候会弹出实体的编辑界面,会让你选择之前导入数据仓库的表、相应的字段,若对字段值无过多编辑,直接双击即可。另外还会有一个选项选择自动/手动获取映射关系,推荐手动。
    3.完成以后进入第二个编辑页面,这个页面主要是关于实体对应的映射源表,以及对实体的一些属性配置,根据业务的情况来进行调整。
    4.全部完成后进入第三个也是最后一个编辑界面,这个界面可以让你确认之前配置的一些重要信息,同时也可以配置父/子实体关系以及实体的展现形式。后面两者项目并未涉及,所以我直接进行了保存。
    5.保存时命名需要规律,尽量避免重复,否则可能导致后面一些很低级的失误。
    

    根据观察,每一个项目创建以后都会有一个公共对象,建议在其中创建子文件夹开发报表(也可以自己创建文件夹开发报表),创建以后,建议将实体、度量、报表等对象也建立子目录保存在对应目录下,并且创建时尽量不要创建多次,或者跨多级文件夹调用,以防出错,同时,创建完成后需要检查一次实体的配置,查看映射、对应表相关配置是否正常。
    根据本次报表开发经验,由于主要展出为报表,可以将实体等对象建立在别的文件夹中,保证展示端只能看到报表。

    另外需要注意一点,若需要用户账号可以查看报表,可能需要给报表以及实体手动设置账号的查看权限,否则会存在权限上的问题导致报表无法顺利展现。我第一张报表开发完成时,使用测试账号进入了Developer来进行测试账报表的完成度,但由于没有给实体赋予测试账号的查看权限,所以运行报表时会报错。

    6.创建提示

    提示相当于查询筛选,可以通过给报表添加提示,保证用户在查看报表时可以根据实体的元素(等对象元素(大概))来决定报表展现的内容。

    提示同实体等对象创建方法相同,但是对象会基于实体元素等条件来进行创建,创建时可以对提示的进行一些相关配置。

    例如:
    是否可以多选
    是否必须回答
    筛选栏样式
    最大、最小回答数
    ···
    

    7.创建报表

    一般来说,当报表相关对象开发完成以后,可以直接进行报表的开发,在创建报表以后找到相应对象所在文件夹,将对象拼接入报表。

    本次项目我所使用的只有两个对象:实体以及提示。实体可以作为报表中的列,直接双击即可导入报表,可以通过光标拖拽进行调整,亦可以通过web端直接编辑报表列宽等格式。提示需要进行手动拖拽到筛选器栏,并且提示顺序的不同会影响到在web端的使用效果。

    报表在完成对象导入以及编辑后,可直接运行查看效果,但不推荐,在数据量较大的情况下,直接在Developer中查看数据很可能回存在卡顿现象(根据服务器来决定),可以在报表开发完成后先进行保存,之后在web端通过最高权限账号进行效果的查看以及更改。

    报表以及对象的每一次编辑保存后都需要手动进行更新框架的操作,保证改动同步至项目中,同时,报表每次查询默认会开启缓存机制,即当报表相关实体对应的数据表数据清空,报表依然会缓存上次运行的结果,所以如果需要进行实时数据展现,可能需要涉及关闭缓存机制。

    8.账号赋权

    报表确认展示效果无误后,可以进行用户账号的建立,用户账号通常只有查看权限,根据需求的不同,也需要对用户账号设置限制,使他们所获取的数据在限制范围内。

    用户的创建也在项目—>管理下进行,管理下有一个关于用户管理的子选项,通过该选项可以查看到的各个用户组的信息,也可以选择手动创建用户组。

    用户组下可以建立多个用户,在创建时除了基本的密码账号设置,亦可以设置用户在不同项目的权限。对报表以及实体的赋权可以通过右键其所在文件夹的属性中,递归赋予查看权限。

    用户查询限制需要通过安全筛选器实现,也可以在编辑用户中针对不同项目创建不同的安全筛选器,安全筛选器与筛选器创建上并无太大区别,都是结合实体元素限制用户查询的范围在自定义的实体元素范围内,例如:一个实体含有A\B\C三个元素,我可以通过安全筛选器限制用户查询该实体只能显示A元素所对应的数据。安全筛选器启用后,不仅对实体,对报表以及提示均会生效(有时候亦可能不起作用)。

    9.查看效果

    用户账号的赋权以及对应项目的对象权限设置完成后,可以直接通过Web端来登陆访问项目,查看对应的报表效果是否可行。

    10.Dossier

    Dossier也叫文件集,在我的理解看来,它可以通过导入数据的形式对数据进行相应的展现,有点类似于报表的UI界面,相较于报表,Dossier具有更好的观赏性,并且结合Dossier亦可以做到报表的效果,对数据的展现以及筛选、图形化数据展现等等效果都可以实现,编辑上相较于报表亦略显简易,但存在一个问题,导入数据集后,Dossier的数据集有时候不会随着随着数据的更新而更新,因此推测,当Dossier数据导入后,数据就作为一个备份保存在了这个对象中,并不会收到实际数据变动的影响,因此,若需要效果会随数据的变动而自动改变,则使用报表更为稳定(不启动缓存)。

    结尾

    本次流程偏向初入门开发流程,并且由于我直接使用存储过程得到了需求所要的效果数据表,并未通过维度表结合MSTR的形式来进行展现,这一方面会在后期有机会接触时更新,写的或许很粗糙,请见谅。

    更多相关内容
  • 让新手快速了解百度echart报表开发流程,内容简单详细,并有源代码,简单易懂。
  • 报表开发流程

    万次阅读 多人点赞 2019-08-26 23:24:10
    报表开发是数据分析师的常见工作之一。报表是业务监控必备工具之一(用数据说话),另一方面,报表监控的指标通常都是业务相关的重要指标,做...本文梳理报表开发的主要流程及注意事项,在不同的实际操作场景下涉及到...

    报表开发是数据分析师的常见工作之一。报表是业务监控必备工具之一(用数据说话),另一方面,报表监控的指标通常都是业务相关的重要指标,做报表的过程也是深入了解业务的过程。

    把数据分析分为“描述、解释、预测、控制”4个层级。那么报表开发就对应“描述”这一层级,也就是要做到准确、及时地监控业务数据。

    9步教你玩转报表开发

    描述、解释是最常见的工作内容

    本文梳理报表开发的主要流程及注意事项,在不同的实际操作场景下涉及到的环节可能不一样,本流程仅供参考。

    9步教你玩转报表开发

    报表开发的主要流程

    报表开发的主要流程

    1. 需求提交

    报表需求发起人就是业务方(通常也称为“需求方”),一般需求方是产品或者运营的同事。

    提交需求时,要提供的信息如下:

    • 业务背景;
    • 报表字段及统计口径(中文描述);
    • 关注数据周期,e.g. 当前年、当前月、近7天、近30天等;
    • 报表发送频率,e.g. 月报、周报、日报、时报、实时等。

    建议制作一个需求模板让需求方填写各项信息,主要用途有两个:

    • 帮助需求方想清楚报表的背景和目的,同时过滤掉一部分不靠谱的需求;
    • 规范填写的信息,以减少沟通成本。

    2. 可行性评估

    该环节主要解决3个问题:

    Q1:有没有必要做?

    • 是否其他系统或报表上可以获得需求方要的数据?
    • 报表的价值或者重要性大不大?
    • 报表的使用频率是不是够高?如果只是偶尔一次,手动取数应该就可以了。

    Q2:能不能做?

    • 一方面要考虑技术上是否可以实现,e.g.实时报表通常由技术人员实现(分析师通常只提供统计口径);
    • 另一方面要考虑权限、合规、安全上的问题,e.g. 报表中是否涉及敏感字段,需求方是否有足够的权限获得这些数据。

    Q3:是不是其他人做更合适?

    数据分析师会做一部分报表,但不是所有的报表都是由数据分析师来做。做报表的目的一方面是便于及时监控业务数据,另一方面,报表相当于“自动化”的数据处理任务,所以报表也能减轻分析师的工作量。

    如果是直接拉取明细数据,或者只是很简单的计数或者求和,那么是否生产库的技术人员应该可以直接做(一般生产库会对接到一个数据后台,不过功能一般比较粗糙)。

    3.需求排期

    9步教你玩转报表开发

     

    在考虑报表需求的重要性、紧急程度的同时,还需要对需求方进行预期管理,留够充足的时间。

    进入“需求排期”阶段就意味着需要登记相应的信息(比如登记在wiki上),e.g. 报表的编号,业务线归属,报表中文名称,报表类型,需求方,需求提交日期,预计上线日期,开发负责人,当前进度等。

    4.数据抽取

    9步教你玩转报表开发

     

    可以简单的把企业数据按用途分为3类库:生产库、分析库、报表库。

    • 生产库,是生产数据直接存储的地方,非开发人员一般是不能直接访问的,生产库的数据通常称为“源数据”(也就是数据源头);
    • 分析库,就是将生产库的数据ETL处理后,放到一个地方集中供数据部门直接使用,数据分析师的日常工作通常依赖于这类库;
    • 报表库,则是存放各业务线报表数据的数据库,通常报表库会对接到各数据产品(e.g. 报表系统、数据展板、自助分析平台等)。

    数据抽取,也就是将数据从生产库抽取到分析库。

    一般业务发展成熟时,报表开发所需要的大部分源数据表都已经抽取过,所以该步骤不一定需要执行。如果是某个业务刚上线或者报表需要用到的表没有被抽取,那么就可能需要执行该步骤:

    • 联系业务线的产品经理以确认生产库的技术接口人;
    • 然后,技术接口人提供库名、表名(英文及中文)、建表代码等源表信息;
    • 接下来,将源表信息传递给数据ETL的同事进行数据抽取。

    5. 代码编写

    这里的代码主要指SQL代码,也就是选择合适的数据表,统计出业务方需要的报表字段数据。

    除了统计口径要准确外,代码编写的时候还要注意3点:

    ①代码规范,代码要有必要的注释、版本信息,注意对齐和命名规范;

    ②文档管理,主要是便于后期的报表维护以及统计口径整合,建议:

    • 代码放到企业网盘备份或者托管到企业内部的git平台;
    • 用wiki登记报表的相关信息,e.g. 报表名称、负责人、代码、数据字典等

    ③建中间表,如果有需要,那就建立中间表,将常用字段整合到一张表,以便于统计分析和口径维护。

    常见的中间表有3类:用户宽表、订单宽表、维表。

    • 用户宽表就是记录用户属性的一张表,比如用户画像的大多数属性都可以放到这张表里,e.g. 基本属性(年龄、性别等)、产品属性(是否开通某服务、产品标签等)、统计属性(首次、常用、最近等)
    • 订单宽表整合订单的各种信息(这里的订单泛指交易订单),e.g.电商订单中的订单来源信息(硬件设备、操作系统、网络类型等)、优惠信息、物流信息、售后信息(退换货等)
    • 维表则是记录字段枚举值的含义的表,因为业务会发生变化,相应的业务类型也会增加调整。e.g. 记录地区编号对应的省市信息表,记录产品各页面名称信息的表,记录不同商品信息(品类、品牌等)的表。

    注:用户宽表和订单宽表之所以称为“宽表”,因为用户或者订单的属性(列)通常比较多(从各个业务线的数据整合过来),且这两类表通常会有增加列的操作(属性扩展);而维表的列(属性)通常比较稳定,一般情况下不会有增加列的操作。

    设计中间表时,除了要求口径的准确性外,最需要关注的是可扩展性,也可以理解为通用性,扩展性要考虑表的维度和计量两个方面:

    i.维度

    • 一般为分类变量,包括日期、二值属性、多值离散属性等,维度就意味着数据表的颗粒度,常见的颗粒度有用户、订单、商品、日期等;
    • 维度上的扩展性体现为,可以进行行压缩或者行列转置等pivot table的操作,一般而言颗粒度越细化(在业务需要的范围内),扩展性越高;

    ii.计量

    • 通常是连续变量,包括数量、金额、时间等绝对量;
    • 计量上的扩展性在于,可以用多个计量的组合计算得到另一个变量,e.g. 计算百分比;

    6. 数据验证

    数据验证主要是核对数据是否准确、完整。

    一般的方式如下:

    • 自检代码逻辑,字段相互验证;
    • 和其他系统的数据比对验证,比如生产库的数据;
    • 由测试人员进行验证;

    数据验证阶段,发现的问题通常在3个地方:

    • 统计逻辑,e.g. 隐藏前提,交叉标签等;
    • 数据抽取,e.g. 数据增量抽取时依赖update_time字段,而该字段在生产库没有同步更新,这种情况下要么改抽取方式为“全量抽取”,要么生产库的字段更新逻辑要进行调整;
    • 生产库改动,e.g. 生产库的业务逻辑改动(业务分流),或者先前的表的字段已被弃用(不再更新);

    如果数据核对不上,则建议按上述的顺序一一排查。

    7. 前端展示

    这个步骤就涉及最终报表的交付形式了,报表的交付形式是在“可行性评估”这个环节确定的。

    按报表展示的载体可以大致分为3类:

    • 自动定时邮件;
    • 网页展示(PC端或者移动端);
    • 独立应用(e.g. 移动端app);

    该环节需要使用到呈现数据的工具(不一定可视化工具,大多数情况还是会用表格展示),这些工具可以是企业内部开发的数据工具(平台),也可以是购买的FineBI, Tableau等方便易用的商业软件。但工具不是最重要的,更重要的是呈现的数据能突出重点、准确反映问题。

    注:理想的数据展示应该是选用了恰当的展示方式,按业务逻辑、有层级地组织了数据,并讲述了一个完整的故事。关于图表可视化建议阅读《用图表说话:麦肯锡商务沟通完全工具箱》这本书。

    9步教你玩转报表开发

     

    8. 报表验收

    在正式上线之前要先对报表进行“自测”,比如:

    • 邮件是否能正常定时发送;
    • 图表是否能正常显示,是否有添加必要的说明提示(e.g. 统计口径等);
    • 显示的数据格式是否OK,e.g. 小数点后位数,单位,坐标轴范围等);
    • 需求方需要用到的功能是否正常,e.g.筛选、交互等;

    完成上述工作后,就可以交由需求方验收了,后续可能需要根据需求方提出的建议做适当的调整,当需求方确认OK时就准备上线。

    9. 报表上线

    报表验收通过,接下来就是正式上线。

    如果是自动邮件,则要确认发送的频率、收件人等信息;

    注:邮件中最好有相应的计算口径说明

    如果是网页或者在独立应用中展示,通常需要申请权限,那么报表上线后需要告知业务费报表申请路径(走OA或者发邮件)、报表名称等信息。

    以上,就是报表开发的主要步骤,涉及到的技术的东西比较少,主要是流程以及信息的沟通,希望对大家有用,欢迎留言交流。

    需要补充的信息:

    i. 本文所述流程是以需求导向的“被动”的报表开发流程,实际上,我们平时也会根据业务需要来“主动”做报表,例如高频的“临时需求”就可以转化成报表需求(自动化的报表可以解放劳动力),另一方面,如果分析师是以项目导向的工作方式,则需要主动和业务方沟通需要有哪些数据需要监控(e.g. KPI、转化率、交易情况等);

    ii. 如果是新业务上线时,报表开发者可能对统计口径一无所知,那么在第一步“需求提出”环节,可以:

    • 让业务方先和产品经理沟通确定报表字段及口径;
    • 然后产品经理再和生产库技术接口人确定技术口径;
    • 产品经理将相应的字段统计口径发送给报表开发者(分析师),并抄送业务方及技术接口人;

    这样业务上线初期,通过报表开发就能积累后续会常用到的统计口径,对报表开发过程中使用到的统计口径进行分类和整理,不管是将相应信息记录到wiki还是建立中间表(这也是数据部分知识管理的一部分),对后续的业务分析都能极大地提高效率。

    iii. 报表也是数据产品之一,凡产品都有其生命周期,报表也不例外,报表后续的维护不仅包括报表字段的增删改,还要进行下线和清理工作,以节省计算资源,同时减少对需求方的打扰。此外,沟通的环节尽量走邮件,一方面是确保信息送达相关人员,另一方面,信息的存档真的很重要。

    展开全文
  • NULL 博文链接:https://zhangzhongjie.iteye.com/blog/1779891
  • 报表开发 A模块概述 模块名 报表开发 模块编号 设M 模块性质普通 父模块列表 子模块列表 元数据准备模型设计报表开发 外部系统列 表 B处理流程和处理逻辑 1处理流程图 B处理逻辑 如图基本的处理流程有三个部分元数据...
  • NULL 博文链接:https://benny1012.iteye.com/blog/366225
  • 中国邮政报表开发流程.doc
  • 中国邮政报表开发流程.docx
  • PAGE 24 中国邮政报表开发流程 TOC \o "1-3" \h \z \u 1报表前期准备 2 1.1登录远程桌面 2 1.2生成xml文件方法一 9 1.3生成xml文件方法二 12 2 报表修改流程 12 2.1创建New Project 12 2.2修改配置 17 2.3报表sql...
  • 某单位报表开发流程概述.doc
  • 某单位报表开发流程概述.docx
  • TIPtop5.3版WEB报表开发流程.pdf
  • EBS HTML报表开发过程

    2018-09-25 16:14:04
    此手册为EBS html报表开发过程,包含如何在ebs中挂菜单等操作
  • TIPtop5.3版WEB报表开发流程[汇编].pdf
  • IFS9水晶报表开发流程

    2018-02-25 03:31:44
    IFS9 ERP中水晶报表开发基本流程,包括基本按照和开发。
  • 用友二次开发 UAP报表 sqlserver存储过程 编译控件 开发总结
  • UAP是用友U8开发的工具,本文主要介绍UAP的使用过程,适合初学者,比较详细,希望可以帮助到你U8UAP开发报表设置方案——存储过程
  • 现在企业的报表开发大部分都使用报表工具完成,成熟的报表工具提供了丰富的显示设置、图表类型、导出打印等功能可以简化报表开发,非常方便。但在实际报表开发中还是经常碰到一些非常棘手的深层次问题,即使是已经...

    前言

    现在企业的报表开发大部分都使用报表工具完成,成熟的报表工具提供了丰富的显示设置、图表类型、导出打印等功能可以简化报表开发,非常方便。但在实际报表开发中还是经常碰到一些非常棘手的深层次问题,即使是已经熟练使用报表工具的开发老手也会很挠头。

    为什么有了报表工具还会出现这些问题呢?

    报表开发,看起来就是将数据按照指定格式的表格或图形呈现出来,这也是报表工具一直以来很擅长的环节。但是,原始数据经常并不适合直接呈现,需要先做一些复杂的处理,这就是数据准备环节。

    从报表工具的眼光上看,数据准备属于报表之外的事情,可以堂而皇之地拒绝处理。但是,拒绝不等于不存在,这个工作总还要做。没有好的工具,目前报表的数据准备还处于比较原始的硬编码阶段,上千行的 SQL、几百 K 的存储过程和大量的 JAVA 代码充斥在报表之后。

    落后的工具必然导致低下的生产效率,会严重拖累整个报表开发的进程,也就出现了前述的“挠头”现象。再由于大多数报表工具的不重视,这个问题迟迟还没有被解决的迹象。

    报表数据准备之于报表有如树根之于大树,如果根本得不到解决,在枝叶上花多少精力都是白费。

    这种深层次问题在报表开发初期一般很少碰到,但随着报表开发的深入这些问题会接连不断地出现了。

    我们在这里收集整理了一批此类问题,以供报表开发者参考。内容比较多,建议先收藏再慢慢看。

    目录

    1. 零编码制作报表可能吗?

    2. 为什么说当前报表开发的工作量主要在数据源环节?

    3. 用存储过程和 JAVA 写报表数据源有什么弊端?

    4. 什么是报表的多样性数据源问题?

    5. 报表的性能问题是怎样产生的?

    6. 什么是大报表?

    7. 中间表是什么?和报表有什么关系?会带来怎样的问题?

    8. 报表热切换是什么意思?

    9. 报表没完没了是个什么状况?

    1. 零编码制作报表可能吗?

    要回答这个问题,首先要明确啥程度算“零编码”?
    以 Excel 为例,如果把写 Excel 公式(包括复杂一些的)看做零编码;而把写 Excel VBA 看做编码的话,

    报表开发是可以零编码的!

    但是,这有个前提:在数据(集)准备好的情况下才可以零编码!

    为什么这么说?
    我们知道报表开发主要分两个阶段:
    第一阶段是为报表准备数据,也就是把原始数据通过 SQL/ 存储过程加工成数据集;
    第二阶段是使用已准备的数据编写表达式做报表呈现。在报表工具提供的 IDE 里可视化地画出报表样式,然后再填入一些把数据和单元格绑定的表达式就可以完成报表呈现了,虽然表达式可能比较复杂,但相对硬编码要简单得多(Excel 公式和 VBA 的关系)。所以说这个阶段是能做到“零编码”的。

    那报表数据准备怎么办?
    很遗憾,这个阶段没法零编码,一直以来只能硬编码,想想我们报表里写的嵌套 SQL、存储过程、JAVA 程序就知道了。为什么报表工具发展这么多年报表呈现已经完全工具化而报表数据准备的手段还这样原始呢?因为这个阶段太复杂了,不仅涉及计算逻辑的算法实现,还涉及报表性能(要知道大部分报表性能问题都是数据准备阶段引起的)。

    那报表数据准备是不是没办法了呢?
    虽然不能做到零编码,但可以朝着简单化的方向努力,将数据准备阶段也工具化,这样可以使用工具提供的便利来简化报表数据准备阶段的工作,从而进一步简化报表的开发。

    那怎么实现报表数据准备工具化?
    要实现这个目标并不容易,像上面提到要考虑的内容有点多,大体来说数据准备工具至少要满足这几方面:
    1. 具备完备的计算能力
    说的有点拗口,掰开了其实在说既然在工具里做数据计算,那得让我什么都能算吧,不能原来 SQL/JAVA 写的放到这里就不行了,该有的计算方法和类库都应该有,最好用起来还比较简单(比原来硬编码难就没意义了),专业的说法叫:计算体系是完备的;

    2. 支持热切换
    这点是相对 JAVA 来说的,通过数据准备工具生成的算法应该是解释执行的,不能每次改完报表还要重启应用,即时修改即时生效;

    3. 具备多源混算能力
    通过数据准备工具可以同时连接多种数据源(RDBMS、NoSQL、TXT、Excel、Hadoop、HTTP、ES、Kafka 等等)进行计算,混合计算,这个数据源读个表、那个数据源加载个文件,两部分数据可以 join 到一起混算。现在我们的数据源太多了,报表常常会跨数据源取数,支持了异构源混算以后,原来还要考虑诸如数据是不是先入到一个库里的事情就不用管了,那叫一个清爽;

    4. 高性能
    直接简化数据准备的工作还不够,实现再简单跑不快也不行。所以,还要高性能,至少不能比原来跑的慢吧,大家都是讲道理的人;

    以上是我们认为数据准备工具应该具备的能力,其他还有一些能力不是特别重要,但如果有最好了。包括:
    * 有没有易用的编辑调试环境,可以很方便地调试算法;
    * 为了更快能不能并行计算
    * 有没有标准接口可以让其他程序或工具调用
    等等,实际要用的时候照着这些特点去找就行了,有益无害。

    说了这么多,总结来说,“零编码制作报表”的确更像一句口号,没法真正做到,但可以不断努力接近这个目标,求其上得其中嘛。

    扩展阅读:

    【数据蒋堂】第 43 期:报表开发的现状
    报表提效资料汇总(体系结构和性能优化)

    2. 为什么说当前报表开发的工作量主要在数据源环节?

    我们知道,报表开发主要有两个阶段。
    第一阶段:数据准备。将原始数据加工成报表需要的结果集(数据源);
    第二阶段:数据呈现。根据已准备的结果集(数据源)编写表达式将数据以表格或图形方式呈现。

    这两个阶段虽然处于同一报表开发过程,但实现方式却大不相同。

    通常原始数据距离报表“能用”还相去甚远,通过 SQL/JAVA/ 存储过程等编码方式准备报表可用的数据源是第一阶段的目标,过程中可能涉及复杂的数据处理过程,因而这个阶段会牵扯较多的精力,占用的工作量也多。

    数据源准备好后,通过报表工具来解决数据以何种方式(图表)、何种样式(外观)呈现的问题,通过点选设置、编写少量表达式就可以快速完成,实现简单,占用的工作量也少。

    可以说,报表开发的工作量主要在数据处理(计算),数据处理后如何呈现,通过工具可以快速完成。

    那是不是报表呈现阶段就不涉及数据处理了呢?
    并不完全是这样。

    早期报表开发
    大概 2015 年以前,报表呈现方式主要以表格(或图表混合)为主,这时通过报表工具实现时就会涉及一定的数据计算,如分组汇总、多源分片、格间计算(同比环比)等。如下图所示:

    计算分布在数据准备和数据呈现两个阶段,两个阶段的工作量相当(各占 50%)。这个时期,数据准备阶段可以把数据准备得“粗糙”一些,然后利用报表工具的计算能力在呈现阶段将数据进一步加工成目标结果进行呈现。比如,我们在数据准备阶段完成关联过滤,再在报表呈现模板中按多个维度分组汇总;或者在呈现模板中计算同比环比。

    当前报表开发
    随着报表工具的逐渐成熟,报表工具提供了更丰富的图形(类型和效果),报表选择图形呈现几乎与表格占比相当了(占比仍在增长)

    使用图形呈现,由于没有“格子”,就无法利用报表工具的计算能力在呈现模板中完成数据处理,而图形本身并不具备计算能力(不包括硬编码),这时自然而然就要在数据准备阶段将前端需要的数据完全准备好,前端工具接收数据直接图形呈现。
    图形设置基本没什么工作量,而后端数据源的准备工作就占了大头,数据呈现和数据准备所占的工作量占比约为 20%:80%。

    当前报表开发的工作量主要在数据源端(数据准备阶段),要提升报表开发效率,势必要解决报表数据源准备效率问题。这也是为什么很多时候用上了一流的报表工具,但报表开发的工作量仍然很大的原因。

    如何提升报表数据源端的开发效率,从而整体降低报表开发工作量?

    借鉴报表开发的发展历史,或许可以获得一些思路。
    早期,报表开发靠完全硬编码,无论数据准备还是报表呈现,后来报表工具出现替代了硬编码方式,将报表呈现阶段的开发工具化,解放了报表呈现阶段的人力(你可以感受一下写代码画报表比用工具做麻烦多少)。

    按照这个思路,用工具替代硬编码就可以提高生产效率,将数据准备阶段工具化就可以解决报表数据源的开发效率,从而进一步提升报表整体开发效率。

    数据准备工具可以是独立的,也可以包含在报表工具内部,后者要求报表工具的能力能够延伸到数据源层面。

    扩展阅读:
    【数据蒋堂】第 10 期:报表的数据计算层
    如何应对报表开发中的复杂逻辑

    3. 用存储过程和 JAVA 写报表数据源有什么弊端?

    我们在报表开发中经常会使用存储过程准备数据,存储过程支持分步计算,可以实现非常复杂的计算逻辑,为报表开发带来便利。所以,报表开发中这样的存储过程并不少见:

    3008 行,141KB 的存储过程,会给报表开发带来什么不好的影响?

    1. 编辑调试性
    存储过程难以编辑调试,这样几千行存储过程的开发周期往往要以周或月计,这样会严重影响报表的开发效率,而业务提的报表需求似乎都“很急”。

    2. 维护性
    相对开发的一次性,维护的工作可能要经常做。实际业务中报表经常会修改,这种现象叫做报表业务的稳定性差。报表的数据准备逻辑变化,修改上千行的存储过程对绝大多数报表开发人员来说都是噩梦。

    有时这样的报表会分两拨人来做,DBA 或专业程序员负责编写存储过程给前端报表开发人员做报表,这样就避免了报表开发人员写存储过程。但这样报表修改的流程会变长,修改一张报表涉及多个人员之间沟通(还包括业务人员),如果负责报表前后端的两拨人隶属不同的团队就更麻烦了。

    3. 知识传承
    从维护性可以直接引出另一个“知识传承”的问题。还是拿上面的报表为例,如果一个新人要改上面的报表,你觉得他要多久能看懂存储过程,改完报表?

    当然,这个问题还涉及很多管理方面的手段,单纯从技术本身来看,这样的报表想要很好地传承知识是很难的。

    4. 安全性
    对存储过程的修改需要较高的数据库权限,而报表经常要改就要经常操作数据库,这对数据库安全也是一个隐患,同样需要强管理机制才能保障一二。

    5. 移植性
    现在绝大多数规定禁止使用存储过程的原因,首当其冲的就是存储过程没有移植性。如果未来数据库发生变化需要迁移,不管将来是更换数据库类型,还是系统扩展(分表分库),大量无法移植的存储过程绝对是最头疼的问题。

    当然,“换库”这件事情即使在今天仍然不会频繁发生,但是只要发生一次就够受了(有国产化或系统扩展预期的就要注意了)。

    6. 耦合性
    从维护性、安全性和移植性看来,存储过程会导致报表应用(前端)和数据库(后端)紧耦合。紧耦合除了会导致前面的三个问题外,还会让数据库编的臃肿,影响数据库性能。

    重要的事情说好多遍,报表的业务不稳定,报表除了经常增加和修改,有时还会删除(不用了),而为这个报表准备的存储过程还在数据库里,这时想要删掉这个存储过程就比较难了。

    为什么?

    因为你不知道是不是还有其他程序在共用这个存储过程,删除会不会对其他程序产生影响。结果就是数据库的存储过程越积越多导致数据库臃肿,而有的存储过程还会涉及自动运行,虽然存储过程可能不再使用,但仍然在消耗数据库资源,长此以往数据库性能下降就成为必然了。

    7. 多源支持
    存储过程运行在封闭的数据库内,无法进行跨多数据源混合计算。关于多源问题,几年前在报表开发还不显著,那时大家都用关系库;但现在不一样了,同一个报表的数据可能来自多个不同类型的数据源(RDB/NoSQL/TxT/Excel/Hadoop/ES 等等),这时存储过程就无能为力了。

    如何搞定这些问题?
    有没有办法解决存储过程带来的这些问题呢?

    当然有!

    没有什么是硬编码解决不了的!用 JAVA 替代存储过程,脱离数据库运行来解决上面的问题(自行搜索 SOA 和微服务理念)。存储过程一个显示的好处是可以分步实现报表数据准备逻辑,这个优点 JAVA 也有,甚至比存储过程更彻底,说句文绉绉的话:JAVA 的离散性更好。

    只是 JAVA 写起来比较麻烦,对于报表开发人员来讲太难了,如果还要加一个修饰词那就是太 XX 难了。存储过程使用的 SQL 语言非常适合做集合运算,分组汇总一句 group by 就写出来了,反观 JAVA 就不具备这个优点了,分组汇总可能要写上几十上百行才行(类库缺失会让开发复杂度急剧上升,想想你为什么不用汇编写程序而要用 JAVA?)。

    JAVA 还有一些其他的问题也不容忽视。

    不支持热切换
    JAVA 还有一个非常致命的缺点,就是不支持热切换。报表经常要改(又来一遍),修改报表数据源以后还要重新编译、重启应用才能生效,对绝大多数业务系统都是不能接受的。报表讲究的不仅是查询立等可取,修改也要实时生效才行。

    报表与应用紧耦合
    与使用存储过程会导致报表与数据库紧耦合类似,用 JAVA 准备报表数据源会导致报表模块和应用的其他业务模块紧耦合不宜维护。

    我们知道,报表大多数情况都是作为一个模块集成到应用系统提供报表查询服务,集成的方式可以是 API(jar 包)方式紧集成;也可以将报表单独发布成服务,通过服务调用的方式松集成,这样报表服务器产生的任何压力或问题都不会影响应用系统(高可用)。*API 紧集成后,由于报表数据源是 JAVA 写的,这样就要和主应用的代码一起打包,无法作为独立的模块维护,而未来想要拆分也基本不可能了;* 服务松集成则完全无法实现。

    所以,用 JAVA 写报表数据源虽然可行,但也不是特别理想。

    那有没有其他办法呢?

    我们比较一下存储过程和 JAVA 的优缺点可以发现,解决问题应该是沿着继承二者优点,改进缺点的方向进行。清晰起见,总结一下需要的点。

     

    把主要的点列了一下,我们的目标就是找到支持这些点的技术手段(问号所在行)。

    易开发、易维护
    这注定了这些能力应该是报表工具内置的,这样报表开发人员自己就能使用工具搞定报表开发,而不必依赖其他人或团队;

    热切换
    热切换要求这个技术应该是解释执行的,这样才能做到实时修改实时生效;

    支持多源
    能够对接多种不同类型的数据源进行混合计算,比如文本和数据库表的 join;

    低耦合、可移植
    数据准备能力和报表呈现能力都报表内置了,自然与应用和数据源都解耦了,未来系统扩展自然毫无压力。

    这样我们可以很容易想到在报表端增加一个计算模块(或引入其他计算工具),来替代存储过程或 JAVA 为报表准备数据,这个模块可以是由嵌入报表工具的脚本来实现,结构可以是这样的

    脚本要具备完善的计算能力(什么计算都能算),支持多源,解释执行允许热切换这些能力。

    这才是报表工具的未来!

    扩展阅读:
    怎样减少报表开发中对存储过程的依赖
    如何应对报表开发中的复杂逻辑

    4. 什么是报表的多样性数据源问题?

    在报表开发早期,报表连接的数据源基本只有关系数据库,而且经常只有一种或者只有一个数据库。

    但今天就不一样了,数据源种类繁多,除了 RDBMS 还有
    1.MongoDB、Cassandra、HBase、Redis 这些 NoSQL 数据库;
    2.TXT/CSV、Excel、JSON/XML 等文件;3.HDFS 等分布式文件系统;
    4.webService;
    5.ES、Kafka 等其他数据源形式
    ……

    当这些都成为报表数据源,报表需要从这些数据源分别或混合取数运算进行报表呈现时,报表就出现了多样性数据源问题。

    具体是什么样的问题呢?

    主要是两个问题,复杂计算和多源关联计算。

    1. 复杂计算
    我们知道,报表中的计算主要集中在两处:

    一处是数据准备阶段。
    通过 SQL/ 存储过程 /Java 程序为报表准备数据,这个阶段可能涉及非常复杂的数据处理逻辑。这样, 计算能力尤其是集合计算能力较强的 SQL 就比较擅长了,通过 SQL、复杂 SQL 可以完成大部分的报表数据准备任务,有些涉及较多业务逻辑的计算还可以使用存储过程,万不得已时用 JAVA 自定义数据源完成。

    这是早期基于单一 RDBMS 开发报表时数据准备的常用手段,主要依靠 RDBMS(SQL)的计算能力来实现。

    但这种方式在多样性数据源的场景下就行不通了,因为有的数据源根本就不支持 SQL,甚至计算能力都比较弱(如 NoSQL),或者根本就没有计算能力(如文本),这样,数据准备计算计算无法在这个阶段实现,就要看另外一处是否可以完成了?

    二处是报表呈现阶段
    根据第一阶段已准备的数据,在报表模板中填入绑定格子的报表表达式或图形来呈现报表是使用报表工具开发报表的常用方式。这说明报表工具具备一定的计算能力,通过表达式可以实现分组汇总、过滤、排序,复杂一些的同比环比等计算。

    但是,报表工具的计算能力是有限的。不考虑性能的情况下,单纯从数据源中读取数据到报表呈现阶段完成数据组织和报表呈现很多时候是做不到的,这也是为什么我们会在数据准备阶段进行复杂数据处理的原因了。

    2. 多源关联计算
    与基于单一的某个数据源进行的复杂计算不同,有时一个报表会同时连接多个数据源,多个数据源之间要混合计算,比如 MongoDB 的数据和 RDBMS 的数据关联运算,文本和 Excel 关联运算等。

    这种跨异构数据源的关联无法直接通过数据源自身的能力实现,只能借助其他方法。


    那报表的多样性数据源问题如何解决呢?

    方法总比问题多。目前大家普遍采用两种方式来解决报表多样性数据源的问题。

    借助 RDBMS
    曲线救国。将多样性数据源的数据通过 ETL 灌到关系库中,再基于关系库出报表,这样就可以避免多样性数据源的问题,转而使用最熟悉的手段来解决。

    不过,这种方式的局限性很大。因为之所以出现多样性数据源,是因为各种数据源有各自适用的场景,换句话说很多是关系库搞不定的,所以才会用这些数据源,比如 NoSQL 的 IO 吞吐能力很强,但计算能力较弱;文本 /Excel 文件适合做临时存储且不需要持久化到 DB;Webservice 则非常灵活,入库的动作就显得过于笨重,…

    且不说多样性数据源的数据是否能转换到关系库中,由于要经过 ETL 的过程,数据的实时性如何保证?数据量较大时除了 ETL 慢,RDBMS 的容量是否够用?查询性能是否满足报表查询要求?等等这些问题都是这种方式要面对的。

    采用这种方式经常是“不得已”,因为解决某类问题上了其他数据源,结果因为出报表又要用回关系库,也不知道隐含了多少辛酸。

    JAVA 硬编码
    通过 RDBMS 来解决报表多样性数据源的问题有这样那样的问题,那直接硬编码怎么样?通过 JAVA 硬编码对接多样性数据源为报表准备数据,毕竟硬编码想干啥就干啥。

    这种方式我们之前有分析过,除了编码难、维护难的问题(报表开发人员基本搞不定),还存在无法热切换(JAVA 是编译型语言)和与业务应用紧耦合(代码要跟业务应用主程序一起打包部署)这些问题。这是我们之前聊过的: 用存储过程和 JAVA 写报表数据源有什么弊端?

    硬编码似乎也不理想。

    事实上,我们只需要增强报表工具的计算能力就能解决这个问题。

    1. 首先,提供多样性数据源的支持,通过报表工具可以连接这些数据源,要实现这一步相对简单;

    2. 其次,提供复杂计算支持,让所有的复杂计算都能在报表中完成。实现手段可以是强化呈现端的计算能力,通过报表格子表达式就能完成这些复杂计算。不过,对于绑定格子的计算(状态式计算)想要支持复杂计算并不容易,在呈现端要兼顾数据处理和数据呈现很多计算就做不了了,而且呈现格会带有很多呈现属性(字体、颜色、边框等等),带着这些属性计算会占用过多内存,严重影响计算性能。


    很难在报表呈现格表达式中完成复杂计算(功能和性能都不满足)

    可以想到的另外一种方式是在报表中增加计算模块用来专门做多样性数据源混合计算,其位置与原来为报表准备数据的 SQL 和 JAVA 相当,只不过是内嵌在报表中,属于报表自身的能力,结构大概是这样

     

    在原有的基础上增加了计算模块,计算模块可以通过可编程计算脚本实现,但对这个脚本能力有要求:

    1. 提供多样性数据源访问接口
    能直接对接多样性数据源是基础,种类越丰富对多样性数据源问题解决得越充分;

    2. 支持复杂计算
    当数据源自身不具备强计算能力时,通过脚本可以完成报表数据准备阶段的复杂计算逻辑,脚本提供丰富的计算类库,可以很方便地实现这类计算,最好比 SQL 和 JAVA 都简单;

    3. 支持多源关联
    可以跨异构数据源关联计算,这是也解决报表多样性数据源问题需要具备的重要能力;

    4. 支持热切换
    脚本修改后可以实时生效,而不会像 JAVA 一样需要重启应用。

    当我们遇到报表多样性数据源问题需要选择报表开发技术时不妨沿着这个方向考量一下。

    扩展阅读:
    【数据蒋堂】第 10 期:报表的数据计算层
    在报表中直接使用多样性数据源

    5. 报表的性能问题是怎样产生的?

    报表性能是总也避不开的话题,报表作为 OLAP(在线联机分析)中的主要应用场景,无论从涉及数据的宽度(表数量),还是数据的广度(查询范围)都可能非常巨大;而且在报表中还经常伴随非常复杂的数据处理逻辑,这些都会影响报表的运行速度。而服务器环境、数据库环境、JDBC 效率、网络环境、客户端环境这些也都都跟报表性能密切相关。

    报表性能可能跟很多因素有关,非常复杂。这里我们试着从报表运行的各个阶段来分析报表性能问题产生的主要原因及其应对方法。未尽之处,欢迎讨论。

    我们知道报表运行主要分报表解析、数据准备、数据传输、报表计算和报表生成 5 个阶段。除了报表解析是引擎加载解析模板,还未开始运算外,其他 4 个阶段(示意图中黄色的部分)均可能引起性能问题。

    我们在分析报表性能问题时一定要先定位是哪个阶段引起的,抓主要矛盾。定位的方法也很简单,就是分析报表运行日志,很多报表工具都会输出各个阶段的运算时间,看看哪个阶段耗时最长,就是问题发生的主要阶段了。

    1. 数据准备
    报表数据准备是指从数据源中读取数据并将数据组织成报表可用的结果集的过程。在报表中往往是以数据集的形式存在,可以通过 SQL、存储过程或 JAVA 实现。

    数据准备并不是简单地将数据源的原始数据取出就结束了,而是会伴随一些计算过程,有些还很复杂,可以想想一下平时我们开发报表时编写的 SQL 绝大多数情况下都不是简单的 select * from tbl。如果这个 SQL 比较复杂(由于大多数情况都是使用 SQL 准备数据,所以这里我们仅以 SQL 为例,其他数据源可以参考 SQL 数据集的解决办法)运行较慢,就会导致报表变慢。

    这个阶段在数据库中运行,本质上跑的快慢都跟报表无关,但好的报表工具是可以干预优化这个过程的(后面再说)。

    数据准备阶段慢,可以先试着优化 SQL,但 SQL 优化往往复杂度较高,所以也经常采用预计算的方式进行性能优化(这里不讨论硬件升级、数据库扩容等物理优化手段)。

    (1) 优化 SQL
    我们知道复杂 SQL(关联多、嵌套多)是比较难优化的。数据库的透明化机制让写 SQL 时不用关心底层的执行顺序,由数据库优化器自动执行,这样可以简化编写 SQL 的难度,但过于透明的机制让我们很难干预 SQL 的执行路径,也就很难优化 SQL 了。

    (2) 预计算
    SQL 无法优化或优化效果不理想时,通过预计算可以提升报表数据准备效率。将报表需要的结果集事先加工出来存储到中间表中,报表查询时直接读取加工好的结果集,这样就可以节省大量计算时间,从而提升报表性能。预计算本质是用空间换时间的手段。

    不过,预计算的缺点也非常明显,你不妨先思考一下有哪些问题?

    主要的问题有两个:时间问题和空间问题。

    时间问题
    预计算需要“事先”加工,其本质是一个 ETL 过程,这样就会引起两个时间问题,数据的实时性和预计算的时间成本。

    报表基于预计算的结果查询只能查询预计算时点以前的数据,无法查询预计算到当前时间的数据,这样就导致了数据时效性差,不适合数据实时性要求高的业务场景(比如交易系统)。

    预计算往往会放到业务空闲的阶段进行,比如前一天夜里到第二天上班前,通常还要预留一些时间容错(跑失败了要重新跑),这样可能留给预计算的时间也就 5、6 个小时,这个时长基本是固定不变的,而数据规模、业务复杂度、报表数量都会不断增长,未来极有可能会引发预计算跑不完而影响业务使用的问题。

    空间问题
    预计算的结果是要落地的,往往会存储在数据库物理表中,这样的表多了会占用大量数据库空间,引起数据库容量问题;另外这样的表多了还会带来管理上的问题。

    预计算的应用范围很窄,而 SQL 又比较难优化,还有什么其他优化手段吗?

    (3) 借助其他高性能计算引擎
    在数据库内搞不定报表数据准备阶段优化时可以引入其他高性能计算引擎,这在业内并不少见,但几乎所有技术都是采用独立存储 + 分布式架构来输出高性能的,这对报表应用架构(主要是数据库)的改变就有些大了,难度很大。

    比较简单直接的方式是在报表内部就能提供改变 SQL 执行路径的手段,并且可以改善那些显著低效的 SQL 算法(比如 topN),这样就可以在不改变应用架构的情况下实现数据准备阶段的优化。

    这就要求报表工具提供数据准备阶段的计算能力,既可以分步执行 SQL(指定执行顺序),还可以改善算法效率。其表现形式可以是一种内置在报表工具中的计算脚本,脚本具备分步计算和强计算能力。


    报表工具计算模块提供可干预 SQL 执行路径能力和高效的强计算能力


    2. 数据传输
    报表通过 JDBC 接口访问数据库读取所需数据时,如果数据量比较大或者数据库 JDBC 性能较差(要知道各种数据库的 JDBC 效率是不同的)会导致数据传输时间过长,导致报表变慢。

    由于我们没法改变数据库的驱动,我们只能在报表层面想办法。一个可行的办法是通过并行取数来提速。

    (1) 并行取数
    通过建立多个数据库连接(这时要求数据库相对空闲),采用多线程的方式同时读取报表所需数据,可能是同一个表,也可能是多个表关联计算后的结果,这样数据传输的时间理论上就会缩短到原来的 1/n(n 是线程数),从而提升报表性能。

    那么这种并行取数实现起来难度如何呢?

    因为目前大部分报表工具不支持并行取数,要想通过并行来加速数据传输只能自己使用 JAVA 硬编码来做。我们曾经讨论过在报表中使用 JAVA 硬编码准备数据的弊端,而编写并行程序难度又提升了一级,要知道,并行以后还要归并(merge)各个线程的计算结果,merge 不是简单地纵向拼接就完了,有时还涉及分组和顺序。

    使用支持并行取数的报表工具
    比较简单有效的方式是使用支持并行取数的报表工具,报表开发人员不需要考虑数据资源冲突、结果归并等复杂问题就可以简单实现。

    (2) 异步传输
    当数据量较大时,可以通过异步机制将数据分批返回给报表,报表接收部分数据后就立刻呈现,后台同时进行不间断的数据传输,这样就可以提升报表的呈现速度。

    异步传输需要考虑很多方面,不建议自己硬编码实现,最好使用支持异步传输功能的报表工具,简单快捷。

    3. 报表计算
    数据传输完成后,报表引擎会根据已准备数据和报表表达式运算报表,这个阶段也是非常容易出现性能问题的。

    性能问题常见于多数据集报表。

    现在很多报表工具都提供了多数据集能力,允许开发者在一个报表中建立多个数据集,这样可以分别组织数据,尤其当数据来自不同数据库时,多数据集尤其方便。但这种方式为报表开发带来便利的同时却会带来很严重的性能问题。

    我们知道,多数据集的关联是在报表单元格的表达式中完成的,类似这样 ds2.select(ID==ds1.ID),报表引擎在解析这个表达式时会按照顺序遍历的方式完成关联,即从 ds2 中拿出一条记录,到 ds1 中遍历,查找 ID 相同的记录;然后再拿第二条再去遍历查找;…
    这个运算复杂度是平方级的,数据量小的时候没什么影响,数据量稍大时性能就会急剧下降。

    另外,报表单元格还带有大量呈现属性(颜色、字体、边框等),带着这些属性运算也会拖慢报表的运行速度。所以,对于数据量较大的多个数据集,最好在数据准备阶段使用更高效的关联算法完成关联。

    在数据准备阶段完成关联

    将多数据集关联转移到数据准备阶段完成,通过 SQL 就可以实施更加高效的关联,只是 SQL 只能基于单一数据库操作,如果数据来自多个数据源时就不灵了。这时,最好报表工具在数据准备阶段还提供诸如 HASH JOIN 等高性能关联算法,以便满足异构数据来源时的关联运算。HASH JOIN 算法可以整体地看待几个数据集,效率比报表工具采用的过滤式关联要高得多,几千行规模时几乎是零等待。

    4. 报表生成
    报表计算完成后会生成引擎会将计算结果以 HTML 的形式输出,生成最终要呈现报表。这个阶段的性能问题主要有两方面。

    (1) 页面渲染慢
    当报表中添加了大量的呈现效果(隔行异色、背景图、警戒色等)时,页面渲染的速度就会变慢。减少过多的报表效果使用可以提升渲染速度;如果这些效果是必须的,那就要比拼使用的报表工具的能力了。

    另外,如果报表单页的内容过大也会影响页面呈现的速度。对于比较高或者比较宽的报表呈现时建议采用分页方式输出,从而提升页面呈现效率。

    (2)客户端环境差
    总体上是跟用户端环境有关系,比如网络问题、设备问题等,遇到时需要具体分析。

    通过了解报表运行各阶段可能出现的性能问题,以及对应解决办法,有些我们可以硬编码或借助其他技术来解决,有些还需要报表自身来提升。最直接的方式是使用能够提供这些能力的报表工具,这个工具大概要具备这些特性才能帮助我们有效解决报表性能问题。

    1. 支持分步
    这样可以有效优化 SQL 执行路径,提升数据准备效率;

    2. 内置强计算能力和高效算法
    能够改善原有低效的算法,提高数据计算效率;
    支持 HASH JOIN 等高性能关联算法,以减少在呈现模板中进行多数据集关联;

    3. 支持并行取数
    能够通过多线程并行方式提升数据传输速度效率;

    4. 支持异步读取
    提供异步取数异步呈现机制,加速大数据量报表的呈现效率;

    5. 支持多数据源
    提供多样性数据源接口,并能够进行多数据源关联运算(同 2)。

    扩展阅读:
    【数据蒋堂】第 3 期:功夫都在报表外 - 漫谈报表性能优化
    性能优化是个手艺活
    如何分析报表性能问题

    6. 什么是大报表?

    实际业务中有些报表比较“大”,查询出的报表数据行数可以达到几千万甚至上亿,这类行数很多的报表通常被成为“大报表”。大报表大部分情况下是清单明细报表,少量是分组报表。

    大报表查询通常不会采用一次性取出所有记录再交给前端呈现的方式,因为这样要等很久,用户体验极差;而且报表服务器内存也吃不消。

    常见的方式是通过分页来呈现大报表,一次只取一小部分数据,取数结束后立刻交给前端呈现,当页码变化时再取出相应页数的数据,这样可以加快报表呈现速度,用户几乎没有等待感。

    具体如何实现呢?有几种方式。

    1. 数据库分页
    业界最常用的做法是使用数据库分页来实现,具体来讲,就是利用数据库提供的返回指定行号范围内记录的语法。界面端根据当前页号计算出行号范围(每页显示固定行数)作为参数拼入 SQL 中,数据库就会只返回当前页的记录,从而实现分页呈现的效果。

    主要借助关系数据库自身的能力,每种数据库实现上会有所差异,Oracle 可以使用 rownum,mysql 则可以 limit,具体实现网上有很多资料这里不再赘述。

    数据库分页有没有什么不足?任何技术都有其应用范围,数据分页的问题主要集中在以下 4 点。

    (1)翻页时效率较差
    用这种办法呈现第一页一般都会比较快,但向后翻页时,所使用的取数 SQL 会被再次执行,并且将前面页涉及的记录跳过。对于有些没有 OFFSET 关键字的数据库,就只能由界面端自行跳过这些数据(取出后丢弃),而像 ORACLE 还需要用子查询产生一个序号才能再用序号做过滤。这些动作都会降低效率,浪费时间,前几页还感觉不明显,但如果页号比较大时,翻页就会有等待感了。

    (2) 可能出现数据不一致
    用这种办法翻页,每次按页取数时都需要独立地发出 SQL。这样,如果在两页取数之间又有了插入、删除动作,那么取的数反映的是最新的数据情况,很可能和原来的页号匹配不上。例如,每页 20 行,在第 1 页取出后,用户还没有翻第 2 页前,第 1 页包含的 20 行记录中被删除了 1 行,那么用户翻页时取出的第 2 页的第 1 行实际上是删除操作前的第 22 行记录,而原来的第 21 行实际上落到第 1 页去了,如果要看,还要翻回第 1 页才能看到。如果还要基于取出的数据做汇总统计,那就会出现错误、不一致的结果。

    为了克服这两个问题,有时候我们还会用另一种方法,用 SQL 游标从数据库中取数,在取出一页呈现后,但并不终止这个游标,在翻下一页的时候再继续取数。这种方法能有效地克服上述两个问题,翻页效率较高,而且不会发生不一致的情况。不过,绝大多数的数据库游标只能单向从前往后取数,表现在界面上就只能向后翻页了,这一点很难向业务用户交代,所以很少用这种办法。

    当然,我们也可以结合这两种办法,向后翻页时用游标,一旦需要向前翻页,就重新执行取数 SQL。这样会比每次分页都重新取数的体验好一些,但并没有在根本上解决问题。

    (3) 无法实现分组报表
    除了清单报表,有时我们还要呈现大数据量的分组报表,报表包含分组、分组汇总及分组明细数据。我们知道,按页取数按照翻页每次读取固定条数(一页或几页)记录,这样根本无法保证一次性读取一个完整分组,而分组呈现、分组汇总都要求基于整组数据来操作,否则就会出错。

    (4) 无法使用其他数据源
    数据库分页是借助关系数据库自身的能力,而对于非关系数据库就不灵了。试想一下,NoSQL 怎么用 SQL 分页,文本怎么做分页?

    报表的多样性数据源话题我们曾经讨论过,在数据规模迅速膨胀的今天,基于非关系数据库出报表已经非常普遍。


    除了数据库分页,还有其他更好的方式吗?

    2. 硬编码实现
    我们发现基于数据库的分页方式强依赖数据源,无法满足其他数据源类型的需要,也就是与数据库紧耦合的。我们需要一个低耦合数据源的实现方式以应对多样性数据源场景,还能同时解决效率、准确性和分组呈现问题。

    按照主流的解题思路,可以通过编码方式实现这个目标,实现思路大概是这样:

    基于数据库时,
    把取数和呈现做现两个异步线程,取数线程发出 SQL 后就不断取出数据后缓存到本地存储中,呈现线程根据页数计算出行数到本地缓存中去获取数据显示。这样,只要已经取过的数据就能快速呈现,不会有等待感,还没取到的数据需要等待一下也是正常可理解的;而取数线程只涉及一句 SQL,在数据库中是同一个事务,也不会有不一致的问题。这样,两个问题都能得到解决。不过这需要设计一种可以按行号随机访问记录的存储格式,不然要靠遍历把记录数出来,那反应仍然会很迟钝。

    基于非数据库时,
    同样设置取数和呈现两个异步线程,取数时通过文件游标(或其他数据源提供的分批取数接口)分批读取数据并缓存到本地,呈现阶段则与上述方式完全一致。

    然后再利用报表工具开放的接口和前端报表进行交互,完成报表的分页呈现。

    做分组报表时,
    就需要一次性取出完整分组,在代码里进行分组汇总,并将汇总结果插入结果集一并返回给前端报表进行呈现,同时还要设置分组记录标志位,以便前端报表在呈现时能够为分组行设置不同的显示效果(如加粗、标红)。

    实现后的效果类似下面这样:gif

    取数线程不停地取数缓存,呈现线程从缓存中读取数据呈现,总页数不断变化

    通过上面的描述,可以看到自己硬编码虽然可以实现,但复杂度很高。除了多线程编程,还要考虑缓存数据存储形式、文件游标、分组读取与汇总,此外借助其他报表工具进行呈现时还要对方开放足够灵活的接口,…,这些都是挑战。

    而且我们只考虑了呈现,如果还要导出 Excel 怎么办?如果还要打印怎么办?毕竟报表既然能查就应该能导出,能打印。这些需求在金融、制造行业都是真实存在的。


    3 使用支持大报表的报表工具
    如果前端使用报表工具开发报表,选用一个直接支持大报表呈现、导出、打印的报表工具则更为直接。工具实现了两个异步线程的大报表机制,同时解决上面我们提到的问题,这些方面都封装好直接使用。

    大数据时代要支持大报表,这应该是报表工具必备能力。

    扩展阅读:
    大清单报表应当怎么做?
    海量清单与分组报表的实现
    如何实现海量数据清单和分组报表
    秒级展现的百万级大清单报表怎么做

    7. 中间表是什么?和报表有什么关系?会带来怎样的问题?

    在数据库中有一类用于保存中间计算结果的物理表,通常被称为“中间表”。中间表主要跟 OLAP(在线联机分析)业务有关,产生的原因主要有以下几方面。

    中间表来源

    1. 计算逻辑复杂
    在 OLAP(报表或查询)业务中,有些计算逻辑很复杂,每次都从头写会导致报表开发过于繁琐,而且有的计算用 SQL 很难写出来。这时会采用中间表事先计算好,再基于预计算的中间结果开发报表。

    计算逻辑复杂常见于报表业务中,以固定报表最为常见;多维分析则比较少见。

    2. 查询性能差
    当查询涉及的数据量很大或者计算逻辑很复杂时查询性能会很差。为了提升查询性能,增强用户体验,通常会把汇总结果实现计算出来存储在中间表中。基于预汇总的中间表查询速度会快很多。

    在实际业务中,大部分提升查询速度的中间表也都是为报表服务的。

    3.ETL 过程转存
    ETL 过程也会产生中间表。ETL 过程中常常会涉及到数据库的数据,正常的 ETL 过程应当是 E、T、L 这三个步骤逐步进行,也就是先清洗转换之后再加载进数据库,最后在数据库中的只是合理的结果数据。但是,E(清洗)和 T(转换)这两个步骤中会涉及到大量数据计算,而在数据库外实施这些计算很不方便,所以实际情况就会是把涉及到的所有数据都先加载进来然后再进行清洗和转换,ETL 过程变成了 ELT 甚至 LET。事先要加载的这些数据在关系数据库中也必须以表的形式存储,这就使数据库中增加了许多并非最终需要的中间表。

    如果观察一下这些跑批任务,你会发现 ETL 任务很多都是为报表业务服务的。

    4. 多样性数据源混合计算
    另一种情况是多样性数据源造成的,这也是为数据呈现(报表查询)服务的。现代应用中的数据呈现经常会涉及数据库外的数据,目前一般的做法是把库外数据定时导入到数据库中,然后就能和数据库内的数据一起运算产生报表,否则很难实现数据库内外的数据的混合运算。这当然也会让数据库中多了一些表,而且,有些互联网上取过来的数据常常是多层的 json 或 XML 格式,在关系数据库中还要建立多个关联的表来存储,会进一步加剧中间表过多的问题。

    通过列举的 4 个中间表产生的主要原因,我们发现一个共同点:中间表大部分情况都是为报表服务的。我们也知道,实际业务中的报表数量非常多,而且报表业务业务不稳定经常会新增修改报表,这会导致中间表数量不断增多。

    中间表会带来哪些问题

    中间表是一把双刃剑,提供很多便利的同时也会带来一些问题。

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

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

    中间表过多还会带来管理方面的问题,对于成千上万张中间表想要梳理清楚恐怕是一件非常头疼的事情。

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

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

    总结来说,中间表会带来管理、容量和性能三方面的问题。

    如何解决中间表的问题?

    可以很容易想到的方式是使用库外文件存储中间表数据,这样中间表脱离了数据库就不会对数据库再产生影响。但是,在实际应用中这种办法却很少使用。为什么呢?

    我们知道,中间表是要再计算的,基于中间表查询的报表还要进行数据过滤,有的还要再次汇总,还可能涉及关联计算,这些操作在数据库里通过 SQL 完成很简单。但是文件没有计算能力,要实施这些计算只能硬编码,用 JAVA 来做,使用 JAVA 来做集合运算又非常麻烦,远没有数据库(SQL)方便。所以采用文件存储中间表的方式使用并不广泛,主要是由实现复杂度过高导致的。

    那还有什么好的方式呢?

    使用支持文件源的报表工具
    既然中间表大部分是为报表服务的,而通过将中间表外置到文件中可以解决中间表带来的这些问题,那么直接使用支持文件源的报表工具是否就可以了呢?

    答案是肯定的。

    我们来看一下要实现这个目标,报表工具要具备哪些能力?

    (1) 丰富的计算类库
    要解决文本计算难的问题,报表工具要提供丰富的计算类库,除了能完成所有数据处理任务(都能算)以外,还要实现简单,这是基础,太复杂了没法用;

    (2) 多样性数据源接口
    支持多样性数据源以后,就可以不用通过数据库中转直接读取多样性数据源数据出报表;

    (3) 异构数据源混合计算能力
    提供多样性数据源接口后,还要能够进行异构源间的混合计算,这样就可以彻底解决掉多样性数据源带来的中间表问题;

    (4) 高性能
    除了实现简单以外,计算性能也要有保障,从而满足前端报表查询的性能需要。

    具体实现上可以在报表工具中增加计算模块来对接“库外中间表”,结构类似这样

    其中库外中间数据文件可以采用本地文件,也可以使用网络或分布式文件系统,或其他数据源。

    要解决中间表问题,需要报表工具强化自身的计算能力才能实现!

    扩展阅读:
    【数据蒋堂】第 14 期:计算封闭性导致臃肿的数据库
    【数据蒋堂】第 15 期:开放的计算能力为数据库瘦身
    有效减少数据库中间表的报表开发方法
    为什么会有这么多中间表?

    8. 报表热切换是什么意思?

    热切换(Hot Swap)是指在系统不停机的情况下更换系统部件,在报表业务中则是指在不重启报表及相关应用的情况下完成对报表的维护(新增、修改、删除),冷切换则恰好相反。

    报表业务很不稳定,业务开展的过程中会刺激出更多查询统计需求,如果每次需求实现后都要等系统空闲(往往是非工作时间)时重启系统才能让修改后的报表生效,那将会对业务使用造成非常大影响(延迟)。因此在需求经常会变化的报表业务中,热切换显得尤其重要。

    事实上,在报表业务中要实现热切换并不难,只要在开发报表时选择合适的技术手段,避免使用诸如 JAVA 这样的编译型语言(虽然重写类加载器可以变相实现热加载,但过于繁琐,也没从根本上解决问题)即可。

    但在实际应用中我们却看到大量使用 JAVA 来开发报表,造成无法热切换的情况。为什么会这样?

    报表业务有两个特点,一个是报表业务很复杂。报表是一项负责综合性统计的任务,将原始数据加工成业务需要的报表形式要走很长的路,不仅数据处理逻辑繁琐,报表呈现样式也千奇百怪,所谓中国式复杂报表。

    另一个特点是嵌入使用。报表经常会作为应用系统的一部分(模块)嵌入到系统中使用。

    现在报表呈现格式方面的问题已经基本得到解决,以国内成熟报表工具为主导的一批国产软件可以很好地解决中国式复杂报表呈现的问题,而且这些工具大多数采用解释执行机制,报表模板修改后可以实时生效。

    但数据准备阶段的问题却一直没有解决,复杂的数据处理和业务逻辑控制让开发人员不得采用硬编码手段来实现。由于大部分应用系统都采用 JAVA 开发,既然报表是系统的一部分,业务逻辑又这么复杂,硬编码的首选自然是 JAVA 了。这是导致在报表中大量使用 JAVA 导致无法热切换的原因。

    那么如何解决这个问题?

    将报表的数据准备也工具化!

    早期,报表开发完全靠硬编码的时代,大家也普遍采用 JAVA 来“画”报表,这样势必存在无法热切换的问题,后来报表工具出现解决了呈现模板的热切换问题。所以,要彻底实现报表热切换,将数据准备也工具化是一个可行的方向。

    然而,报表的数据准备和报表呈现两个阶段分别使用不同工具会造成报表开发和维护上的困扰,因此,最好的方式是增强报表工具自身的计算能力,将两个阶段都融入可以解释执行的报表模板中,从而彻底实现报表热切换。

    我们知道,报表工具本身具备一定的计算能力,在呈现模板的单元格中可以编写分组、求和、比值等表达式,但由于格子的限制很难处理复杂的数据逻辑,这也是为什么在报表中需要数据集(JAVA/SQL)来准备数据的原因。

    一个可行的办法是在报表工具中增加可解释执行的计算脚本(模块)用于数据准备,这样在计算模块中可以实现任意复杂的数据处理逻辑,同时解释执行的脚本内置在报表模板中实现热切换。

    报表计算模块(脚本)要具备这样一些能力:1. 解释执行
    这是实现热切换的基本能力,数据准备和报表呈现内置在一个报表模板中,采用解释执行机制运行;

    2. 计算体系完善
    能实现所有的数据处理任务,原来在 JAVA 中的报表数据准备计算在脚本中都应该能完成,具备丰富的集合运算类库;

    3. 易开发维护
    实现上要足够简单,这样报表开发人员就能直接搞定数据准备和报表呈现,而不再依赖其他专业程序员;同时在一个报表模板里更易于维护。

    参考资料:
    如何应对报表开发中的复杂逻辑

    9. 报表没完没了是个什么状况?

    可以先想一下自己的部门或项目组是否面临这些问题:
    1. 投入很多技术力量做报表,却还是疲于应付
    2. 用了高端报表工具和敏捷 BI,却还是不够用
    3. 技术高手用来做报表,感觉很浪费 4. 对于频繁多变的报表需求,需要低成本应对方案

    专门用于统计分析的报表业务有一个特点,就是业务稳定性非常差。在业务开展过程中会催生很多新的查询需求,而且已实现的查询需求还会经常变化,这就造成了没完没了的报表。所以经常会有这么一段对话

    报表没完没了是需求使然,无法规避,只能适应,而目前主要的是问题是普遍缺少一种低成本的方案来适应没完没了的报表。

    为什么报表开发成本一直居高不下?

    我们知道,报表工具的主要作用是将报表呈现阶段的开发工具化,使用报表工具可以将原本需要硬编码的工作通过工具来提高生产效率;但报表开发的另一个阶段:数据准备,却仍然在使用原始的硬编码方式处理,有时我们要编写非常复杂的 SQL、存储过程和 JAVA 程序,这样的工作通常要依赖高水平的技术人员才能完成。

    另外,采用过于原始手段会带来报表维护困难,复杂的代码无论从编写还是修改都比较困难,这样又会加剧报表开发成本居高不下!

    除了技术原因外,还有应用结构和团队管理方面的因素也会造成报表开发的成本居高不下。在许多应用系统中,报表是耦合在其中的一些功能,而业务系统的技术环境很复杂,这就迫使报表开发人员也要熟悉这些东西,也就很难把报表开发人员和业务系统的开发人员分开,业务系统上线之后,开发人员仍然要继续坚守开发报表,很难把这项工作转交给客户方的运维人员。

    开发过程中的有效沟通也会影响工作量。我们经常会发现这样的现象:业务人员提出报表需求,等技术人员做好后才发现某些概念术语的理解有误,统计口径不一致,结果并不是业务人员想要的,然后也只能重做,甚至反复多次才能正确实现,严重浪费开发资源。


    如何解决报表开发成本过高?如何低成本地应对没完没了的报表?

    可以尝试通过如下五个步骤来解决这些问题。

     

    1. 引入报表工具

    先把最容易解决的问题解决掉,通过引入专业的报表工具解放报表数据呈现阶段的人力,报表工具可以完成包括中国式复杂报表在内的各种图表呈现。选择成熟且性价比高的工具是这个阶段的主要目标。

    2. 增加计算模块

    引入报表工具后,解放了数据呈现阶段的人力,降低了一定的成本,但占主要部分的报表数据准备阶段仍未解决。

    数据准备阶段的特点是:1. 编码困难,没有普适的工具 2. 对人员要求高,需要高水平技术人员完成 3. 实现周期过长,难以适应多变的报表需求 4. 硬编码耦合性高,依赖数据库和 JAVA 都都会造成紧耦合 5. 运维过于复杂,修改维护成本提高

    这时,我们需要沿着第一步的方向继续前进,将数据准备阶段也工具化。比较好的方式是
    在报表工具中增加用于数据准备的计算模块,将原来使用 SQL/ 存储过程 /JAVA 实现的数据准备算法,全部通过计算模块完成,使得报表开发彻底工具化,简化开发,降低成本。

    计算模块的能力可以通过脚本来实现,在脚本中内置各种丰富的计算类库,让报表开发人员独立就能完成数据准备阶段的工作,从而全面接管报表的开发,而不再依赖其他专业程序员。

    这里尤其要注意,报表计算模块需要具备这样一些能力。

    1. 易于编码
    包含丰富的计算类库,可以很方便地完成各类数据计算任务;必要时还能提供可视化的编辑调试环境进一步简化这个阶段的开发;

    2. 支持热切换
    计算模块需采用解释执行机制,这样可以很好地和前端报表呈现模板结合在一起,报表修改后可以实时生效,无需重启整个应用;

    3. 支持多样性数据源
    提供 RDB、NoSQL、文本、Excel、hadoop 等多样性数据源接口,报表直接基于多言行数据源开发,也可以进行混合计算(如 Excel 和 RDB 的表 join);

    4. 高性能
    计算模块的计算性能不能低于原来 SQL/JAVA 的计算性能,最好高于原来的实现方式。

    报表开发全面工具化以后,就可以获得更高的报表开发效率,进一步降低报表开发成本。

    3. 独立报表模块

    报表开发全面工具化以后,就可以着手梳理应用结构,独立报表模块,从而将报表模块从业务系统中解耦出来。

    1. 梳理数据源
    首先梳理数据源,将报表业务相关的数据源都整理出来,以后的报表开发只需要和这些数据源打交道;同时为下一步剥离报表业务做准备。

    2. 剥离报表业务
    将数据源和业务应用中与报表相关的数据准备(复杂 SQL、存储过程、中间汇总表、自定义 JAVA 类)全部转移到报表工具中实现;同时将这些内容从数据库和业务应用中清除,完成报表业务剥离。

    3. 独立报表模块
    报表业务完全剥离后,在报表工具中实现的报表在物理上就可以独立于数据源和业务模块存储,不再与业务系统和数据源紧密耦合,完全独立报表模块

    4. 调整应用结构
    独立报表模块后,报表模块与业务模块共享数据存储;应用系统调用报表模块为用户输出报表结果;同时解释执行报表模块支持热切换,即改即用,无需重启应用。

    独立报表模块以后,报表就可以单独修改和维护,清晰的应用结构会进一步降低报表开发成本。

    4. 建设报表团队

    报表模块独立后,建设专门的报表开发团队,不再需要高成本应用程序员或 DBA 参与报表开发,进一步降低报表开发成本。

    报表开发人员就无需应对纷繁复杂的应用环境,更无需关系应用架构,只需根据已有架构开发报表就可以了。半年以上工作经验的技术人员就能胜任(其实,理工科应届毕业生就可以了,甚至高中学历都行)。

    简化报表开发后,还可以尝试将持续的报表开发工作移交给客户方的本地运维人员,这样不仅能降低开发商的成本,还能提高对客户的响应速度。

    5. 完善沟通机制

    最后就是建立有效的沟通机制,减少交流中的误解。

    一个简单可行的办法就是建立企业内部的报表知识库,技术形式上搞一个论坛即可。把以前做过的报表收集到论坛上加以评注,并提供搜索功能。

    当有了新的报表需求时,可以搜索历史库中是否曾经做过类似的报表(出现过相同的业务术语)。历史报表中保留有相关代码或公式,而这些形式化的信息不会有歧义,这就能帮助新的开发人员正确理解业务术语。

    甚至许多报表部分还可以被直接复用,在人员变动时也可以最大限度地保证业务知识的继承。


    应对报表没完没了是一个长期的过程,是涉及技术、管理等诸多方面的综合性事务。当这些步骤完成以后就可以全方位应对没完没了的报表了。

    扩展阅读:
    应对报表没完没了的五个步骤
    一劳永逸地“解决”没完没了的报表开发

    结语

    报表做不完,都赖数据源;报表开发快与慢,数据准备是关键。

    通过提升报表工具的数据准备能力可以解决大部分报表开发过程中的深层问题, 从而通过改进生产工具来提升生产效率。这样,在选择报表工具时,除了能满足呈现方面的需求外,也要关注工具本身的数据准备能力,自然是越强越好。

    关于当前主流报表工具在这方面的能力,可以搜索“十大活跃报表深度点评”,其中有深入的评论。

    我们还将持续关注报表开发中遇到的各类难题,对这方面感兴趣的同学可以再搜索“乾学院”上的免费商业智能课程,进一步了解和学习。

    展开全文
  • 关于银行报表开发简单思路解析(MYSQL存储过程) 需求分析: 该表为简易银行报表模板,一般为行列模式。 基础表设计: 1.根据业务种类建立对应业务的维度表,一般为客户维度表,产品维度表,资产维度表等 2.根据...

    关于银行报表开发简单思路解析(MYSQL存储过程)

    需求分析:
    在这里插入图片描述
    该表为简易银行报表模板,一般为行列模式。

    • 基础表设计:
      1.根据业务种类建立对应业务的维度表,一般为客户维度表,产品维度表,资产维度表等
      2.根据字段一、字段二等行项目,来处理加工出来一张事实表。也可以简单的理解为将最终报表中的处理逻辑单独做一张事实表。
      3.根据报表字头的标题做一张码表,每一行赋予一个Index_No字段。并且按照递增排列。
      4.一般都有一张时间维度表,这个都是默认建立的,可以直接用。作用就是用来截取日期段来循环插入数据。
    • 处理逻辑:
      1.根据报表样式中的列字段按照业务模式为指标建立若干张张临时表,表中的数据为按报表模板中的字段一等等的select结果。
      2.根据临时表与码表关联select出报表样式中的所有数据(不含合计)
      3.插入合计数据。
      4.转换最终金额为万元。
    • 伪代码:
      创建存储过程,先按照思路做出两张临时表,而后把每一行的数据select出来,插入到最终报表中,接下来就把合计select出来插入到最终报表,最后把数据单位格式更新。
    • 代码实现:
    CREATE DEFINER=`dap_app`@`%`PROCEDURE `dap_app` . `P_F_RPT_G0602_ASSET_LIAB_SITUAT_SUB`
    ( 	IN I_BEGIN_DATE INT, 
    	IN I_END_DATE INT 
    )
    /*
    --=========================================================================-
    --对象编号:
    --对象名称:
    --对象表示:
    --创建人:
    --创建日期:
    --功能描述:
    --处理逻辑:
    --修改说明:
    --未确定问题:
    --待优化问题:
    --=========================================================================-
    */
    begin 
    	declare v_oc_date,v_m_begin_date int;
    	declare done int default 0;
    	
    	-- 游标循环处理输出入参数日期区间的数据
    	declare cur cursor for 
    		select oc_date from dim_date
    			where oc_date between i_begin_date and i_end_date
    			order by oc_date asc;
    	--将变量done设置为1,用于循环中判断是否交结束
    	declare continue hadnler for not found set done = 1;
    	
    	--打开游标
    	open cur;
    	dateloop:loop
    	--游标向前走一步,取出一条记录放在变量v_oc_date中
    		fetch cur into v_oc_date;
    		if done=1 then
    			leave dateloop;
    		end if;
    	--获取月初数据
    	select min(oc_date)into v_m_begin_date
    		from dim_date
    	where oc_month = v_oc_date;
    	
    	--删除输入日期表数据
    	delete from F_RPT_G0602_ASSET_LIAB_SITUAT_SUB
    		where data_dt = v_oc_date
    		
    	commit;
    		
    	--插入表数据
    	insert into F_RPT_G0602_ASSET_LIAB_SITUAT_SUB
    		(字段1,字段2,字段3,字段4)
    	with asdf as (
    	*** as puc1
    	*** as puc2
    	*** as puc3
    	***),
    	jubs as (
    	*** as puc1
    	*** as puc2
    	*** as puc3
    	***)
    -- 行内容1
    	select 
    		v_oc_date as data_dt,a.标题1,a.标题2,a.标题3,
    		bb.puc1,  	-- 此处对应临时表的对应数据 > 进而对应最终报表的第一行数据
    		cc.puc1		-- 此处对应临时表的对应数据 > 进而对应最终报表的第一行数据
    	from 码表 a
    	left join asdf bb on 1=1
    	left join jubs cc on 1=1
    	where Index_no = 1 -- 此处为取字头的逻辑 > 进而对应最终报表的第一行数据
    union all
    -- 行内容2
    		select 
    		v_oc_date as data_dt,a.标题1,a.标题2,a.标题3,
    		bb.puc2,
    		cc.puc2
    	from 码表 a
    	left join asdf bb on 1=1
    	left join jubs cc on 1=1
    	where Index_no = 2 -- 此处为取字头的逻辑
    	
    	...
    	
    	commit;
    	
    -- 生成合计
    	insert into 表名
    	(字段名
    	字段名)
    	select 
    		* as Index_no,
    		'' as categ_level1_1,
    		'' as categ_level1_2,
    		'' as categ_level1_3,
    		字段名,
    		字段名
    	from 最终表
    	where Index_no = ***    -- 根据Index_no来进行合计
    	and 日期限制
    
    	commit;
    	
    --将相关列转换单位
    	update 
    	set 字段名 = 字段名+计算式
    	where 日期限制
    	
    end loop dateloop
    close loop
    
    end 
    
    展开全文
  • 数据报表设计流程一:构建分析体系 1、面向业务结果的分析 b端产品经理不同于c端,业务是一切产品设计的核心,必须围绕业务进行产品设计。首先要明确分析目的,并进行业务诊断,最重要的是打通分析链路。 例如要分析...
  • 帆软报表 服务器搭建及开发流程

    千次阅读 2021-01-19 16:51:33
    目录 ...【安装流程参考官网文档,非常详细】 下载安装设计器 服务器部署包安装方式: https://help.finereport.com/doc-view-2804 报表访问地址: http://localhost:8080/webroot/deci..
  • 1、查询控件 2、单元格扩展 3、子父格 4、层次坐标 5、动态格间(比较、占比、环比、逐层累计、跨层累计) 6、条件统计 7、主子报表 8、分组报表 9、自由报表 ...24、聚合报表开发 25、决策报表开发 ...
  • congo报表开发流程

    2009-05-23 22:38:06
    介绍congos8.3如何制作报表,以及congos报表的整个开发流程
  • 用友T+RAP报表开发

    2018-04-18 13:59:58
    RAP(Rapid Application Platform)快速应用开发平台 ...RAP涵盖了整个T+业务开发的全过程,包括档案、单据、报表、自定义页面等,可以快速对档案、单据和报表的列和栏目进行增删改,快速自定义页面和自定义按钮。
  • 本套教程采用vs2012+sql2012开发,以销售明细表为例,讲解了常见报表开发过程,既包含了传统的表格形式的报表、又包含了柱状图(条形图)、饼状图、环形图、南丁格尔图、曲线图、折线图、面积图等,前端使用ajax...
  • GR 凭证报表开发流程 李泽昌 2020.06.17 第一部分:入口程序的开发 报表作业也是程序,首先要去azzi900注册程序和到azzi910注册作业(打印入口主程序,用于输入查询条件和调用模板) 前往设计器签出规格和程序 (在...
  • ABAP OOALV报表开发

    2018-06-30 20:20:31
    ABAP OOALV报表开发,定义变量,选择屏幕定义,创建类,调用函数
  • 图片详解XtraReports报表开发过程,如何创建报表,如何连接数据源.
  • 帆软报表开发学习笔记(二)

    千次阅读 2020-08-19 11:04:30
    `帆软报表开发学习笔记`帆软报表数据准备(20200817)帆软报表数据准备(20200818) 帆软报表开发学习笔记 帆软报表数据准备(20200817) 数据连接: 制作报表前需要定义数据来源,最常见的就是数据保存在数据库中,并且...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 108,305
精华内容 43,322
关键字:

报表开发流程