大型报表项目
本人曾经Lead过一个微软的报表项目。一年多的时间里,项目规模从只有我一个人发展到五个人再到最后部门重组被砍掉,期间亲手为微软开发和维护了361份SQL Server Reporting Services报表,其它类型和格式的报表更是数不胜数。这之后的工作也或多或少地涉及报表开发,因此个中坎坷可以说是有深刻体会。一些切肤之痛,不是随便玩玩的人能够感受到的。
首当其冲的便是开发组的经验在成员之间难以分享。说白了,我不知道你做了什么怎么做的,你也不知道我做了什么怎么做的。因为通常来说,一份报表往往是由一位开发人员独力完成的,协作开发同一份报表的情况并不常见。整个开发过程,包括数据源的访问方式,数据读取的限制,业务逻辑的各种处理,到页面呈现的各种设置,甚至配色和数据格式的讲究,都只有负责开发的人清楚。万一某个报表开发人员休假,其余的人很难接手他的工作,只能勉力维持报表正常运行。为了解决这个问题,通常会有PM或者业务方面的人管理报表,然而人力总是有限,而且项目规模大起来记性常常不够用,一不小心就忘了什么。为此我曾经提议应该每日或者每周彼此回顾(review)一下近期的工作,可惜迫于报表用户给的进度压力(有不少微软高层),老板不太支持。事后看来,当报表项目发展到一定程度,其实是很有必要的。
第一个问题带来第二个问题,就是不知道我们已经做了哪些工作,容易导致重复开发。今天来个人请求某个数据的环比,我们给他做了,再过十天半个月又有人来要某个比率,其实就是前面的环比换个名称,但作为非业务部门我们不知道这俩是一回事,于是又开个Task再做一遍。呵呵,一个数据可以做出两倍的工作量来,显得好像我们“工作很充实”(有理由多要点年终奖),不仔细全面地回顾还真是难以意识到。这还只是比较好察觉的情况,更麻烦的还有。当一个项目转变为长期项目,就要特别考虑人员的更迭,报表项目也不例外。我们这个项目在我加入时已经做了两年了,一些报表是很早很早以前做的,我们都很难搞得清它们的具体作用以及包含的数据——报表数量实在太多了。万一有人要求的数据,其实恰好在那些老报表中已经存在,我们是无法察觉的,最终还是一不小心就开个task出来。还好当时的PM待的时间够久,极大的避免了这种情况,否则我们再招十个人都不够用!但即便如此,仍然发生过不少这样的状况,实在令人为难。每个人只能尽力确保自己不做重复的工作,但是团队有没有做重复的工作,就全看PM给力不给力了。
第三个问题,就是报表风格不统一。项目组中我算相对较资深的,即便没什么美工基础,什么地方什么数据应该如何强调,其实是有一套自然规律存在。这就跟红灯停绿灯行一样,人们看到某种颜色某种形状某种字词就会提高注意力。但是团队成员未必对此有一致的认识。这就导致,虽然我们的报表是一个工厂生产的,却花样百出各种规格都有!美工这种东西,很考验天赋,其次是意识,再次是精益求精的态度。我说那个数据过高应该用警戒色,他说他就喜欢蓝色,只要客户不说,配色全看开发的心情,你说能有什么办法?这些很主观的事情,没人规定这种颜色就是比那种颜色更好,你怎么说理去?只要要求的数据都给到位,通常客户不会为此来找茬,一般的报表开发人员也懒得去抠细节,但是做得好看一点,确实让人赏心悦目。最初我意识到这个问题,但是没有美工基础我也不知道应该做成什么样子,于是便想方设法把SSRS报表做成Excel的表格样式,这样报表用户切换着看Excel报表和SSRS报表的时候视觉上就不会有突兀感(毕竟很多报表用户都会同时看Excel报表和SSRS报表)。仅仅是这样小小的变化,居然收到本项目组的历史最高荣誉——一份来自微软高层的表扬信!可见,有些事情用户不说,不代表用户没意见。这在报表领域是个专门的主题,有人写很厚的书讲报表设计。或许集体学习报表设计理论是个比较好的办法。
第四个问题,是报表性能的退化。这是大多数人无法意识到的问题,因为很少人能够长期观察大规模报表项目的性能表现。报表在开发的时候一般性能还是不错的,至少总有办法让它们“看起来不错”。但是当这些报表运行一年两年后,性能是否还可持续?这是个大问题。通常,会有一个甚至若干个数据库专门为报表提供数据。一份报表刚推出那会儿,没有别人竞争资源,完全感受不到性能压力。过个一两年,几百份报表上千名用户时刻都在从这些后台数据库中同时读取数据,对数据库产生的压力已经不亚于一个中小型网站。因此,当初快得飞起的报表,可能也显得老态龙钟了。一些公司配有DBA的还好,可以从技术层面持续优化,没有DBA的团队就惨了。不过即便有DBA,由于报表需求是逐步逐步产生,报表也是一份一份开发,这导致虽然一两份报表单独来看是设计良好的,但是所有报表之间缺乏从全局着眼的整体设计。A报表从a表出数据,B报表从b表出数据,但其实a表b表完全可以合并起来用并且性能更好也易于维护,然而因为A报表和B报表是在不同时期由不同的开发人员做出来的,没有人能够认识到这一点。有时情况则反过来,A报表和B报表都从某表取数据,两者的性能都不好,但其实A报表所需的数据只是该表的一个很小的子集,拆分成a表和b表来用,B报表可能还是很慢但是A报表就能快不少。随着时间推移,数据表的增多增大,数据库中重复的冗余的数据也越来越多,越来越难以管理。如果报表项目够大够长,或许定期重构是个好办法。
最后,许多人说SSRS报表性能不好,SSRS报表不美观什么的。离开那个项目后我也接触了使用其它报表工具的一些项目,比较之下,个人感觉SSRS在开发效率上无出其右,非常适合大规模报表开发。但毕竟SSRS做出来的年代比较早,也可能是出于兼容性考虑(SSRS报表必须能够导出为一般书面文档格式),SSRS报表都是静态报表,跟现在那些动态效果丰富的报表在美观上确实没法比。不过最近微软收购了DataZen并用他们的产品更新了一下SSRS,看起来有所改观,尤其是在移动设备上的显示效果较之前好很多。性能方面,虽然也算是B/S结构的产品,但其实SSRS并不是个重量级的报表工具,性能问题基本都出在数据库查询上,报表呈现并不会产生多大的性能压力。在SSRS的后台数据库有视图以ExecutionLog为前缀,可以查看报表生成过程中不同阶段的耗时,以我的经验主要还是DataSet里面写的数据库查询有问题。
扫描以下二维码参与更多讨论