其实想写这篇东西很久了,但是一直因为自己的懒惰而没有写下来.
项目一直被业务团队追着拿数据,终于抽出了时间来作一个查询子系统,因为项目本身的数据量比较大,好几个表都是千万级的数据,而且硬件本身也是一个问题.所以我们按照教课书的方式来设计这个系统:将统计结果预先生成,当查询需要的时候直接显示结果.
恩,很不错,对吧!但是我们错了.
第一,在系统编写期间,我们耗费大量的精力去面对大量的查询的排列组合问题,我们基本上被这些问题给折磨死了.
第二,当系统完成上线之后,业务团队投诉说系统很多数据都不准确,跟以前手工提数据的时候差很多.
于是悲剧发生了,这个系统上上去之后一直都没有人用过,即使是统计准确的部分,业务团队还是会要求手工提取数据.
然后,我们决定重写这个系统.首先,我们确认了所有统计的条件所代表的意义,我们在这件事上花了两个星期(大约两个星期),但事实表明我们这个时间花得很值得,这个是我从业以来,体会最深的用户的需求与程序员的理解的差距.我们有一大半的需求是理解偏差的.(或许,你会说:你们项目没有词典的吗,没有术语表的吗?额,这个有,但是你能确定所有人的理解都是一致的?)在这里我需要提供以下我们确定需求的手段,很简单的,我们画图,我们画网格图来确定哪些条件的数据在统计范围内,那些不在.这个方法很好用.你们也可以试一下.
接着,我们开始选定技术方案,预先生成数据的方法被否决了,因为条件过多,多得统计结果的数据量会比数据本身还大一到两个数量级.于是我们选择了数据清洗(对就是做数据仓库之前的).我们把清洗好的数据放到了另外一个数据库,每天使用脚本将数据由业务库移到统计库.
最后我们编写初始化脚本,将以前的数据导入统计库.现在这个系统工作的很好,除了一些极个别的怪异需求之外,我们基本上不再需要为业务团队体数据了.
其实做统计系统我们(起码我之前是这样子的)都会这样子想,把统计结果生成了,缓存起来,那么什么事情都没有了.但是,我们真的做的到吗?统计结果是可回溯的吗?统计结果会由于业务的状态而改变吗?系统支持的业务是长期业务还是短期业务?...还有很多很多需要考虑的问题.但是毫无疑问,如果你的项目是b2b的,类似于淘宝那些,确实可以把结果缓存起来,因为数据是不会变得(销售额之类的只会在短期变化的).但是如果你做的是大宗买卖,比如房产系统,房子在两个月内是可以退的,可是你每个星期要出一份销售报表,那么这个就不适合缓存统计结果了(除非客户要求统计结果可回溯,真的有人这样要求过我).
最后,尽信书,不如无书,上面就是一个鲜明的例子.因为所有的数据库类的书,都会假定,业务发生了就不会改变了,起码,在相对长的时间是不会的.但你的系统真的是这种类型的吗?如果不是,你或许需要自己去思考一下这个问题.