数据分析说开去

        数据分析,优雅的说法是数据挖掘,再优雅一点就是前面加上海量俩字,往土了说就是做报表,但不管怎么说,数据分析的成果就应该是各种形式的报表。通过分析历史来做趋势预测,并且做出相应的决策。
        我曾经设计开发过一套报表框架,是业务应用系统方面的,数据量上肯定不能和互联网相比,所以谈不上能解决海量数据问题,但是他能满足绝大多数类型的报表业务,对于很变态的报表需求,也能做到变通实现。开发的特色是配置型开发,原则上不需要编程,偶尔要做一些数据转换方面的开发,但归根到底开发的量很小很小。
        不管在应用系统中也好,在网站也好,数据分析往往是一个边缘模块,它代替不了核心业务,而且要满足各种各样的数据分析需求,写sql、写存储过程,在大多数开发人员眼里,做数据分析是一个低端的工作,所以有句话这么说的:好女不嫁程序员,好男不去做报表。
废话不多说了。


        首先我面临了三十多个报表需求,每个报表最少都有十多个字段,每个报表还都得分日报、周报、月报的形式,表头按指标还要分组展示,一眼看去密密麻麻的。。。公司之前传统的做法就是写存储过程,速度极慢,点个查询几分钟才能出来,客户也习惯了这种方式。看看之前的老代码,后台真正代码没几行,一个存储过程倒有上百行,还都是没见过的函数,个人感觉能写这个能维护这个的还真够牛的(我个人至今不擅长写存储过程)。但我认为这种方式从头到尾都很愚蠢,不光要写非常复杂的sql,前台对应的页面也需要进行开发,工作效率极低。

         那我们回到需求本身,看看中间有什么能从技术上抽离出来做成共用的。于是我对着一个报表excel需求足足盯了半个多小时没动,终于发现了突破口。为什么报表需要使用大量的存储过程,因为最终呈现出的指标内容,其数据来源是异构的,其来源不同,所以需要复杂的sql来强行把它们组合起来,但指标和指标之间,本质上并没有太大的关联关系。去掉A指标,并不影响B指标的展示,B的数据结果并不受影响。举个例子,比如网站要展现一个用户每日pv和每个页面停留的最小时长和最大时长: 

日期 用户IP 当日pv 页面停留最小时长 页面停留最大时长

        但实际上,当日pv和停留时长没有本质关系,展现中去掉时长指标,pv数是不受影响的,反过来也一样,本身他们就是异构数据,数据来源不一样,需求中非要强行展现在一块,就增加了数据分析开发过程的复杂度。存储过程是一种方式,但肯定不是最优的。十多个指标的报表,存储过程开发+后台开发+页面开发+调试测试,怎么也得两天时间。

        那我能不能先建这么一张数据表,里面有pv有时长字段,预先进行原始数据分析,存到这张表,后面展示的时候单表一查就ok了,这样展示的效率是最高的,而且需求方往往不会太在意当前时间点的统计数据,如果是日报,那必然是关心今天以前按日统计的数据,如果是月报,必然是当月之前的统计数据,从日报月报的角度来讲,因为当日当月都没结束,统计当日当月的信息没有实际意义。从更细粒度的角度讲,如果实时性要求较高,那我可以做时报、十分钟报、甚至分报,实时归根到底只是相对的一个概念。

        那好办了,我提前分析数据的策略在需求上是可行的,同时历史数据是不会再变,分析结果也是不会变的,初步方案就是:提前按特定的时间维度分析原始数据、将分析结果入库,展现时直接查单表。

        接着分析指标,看看从技术上如何将这些指标分类,最后我归纳出如下一些指标类型:

       时间指标

       事件主体指标

       展现型指标

       统计型指标

       计算型指标

 

         首先时间事件主体两种指标就好比作文三要素中的时间和人物,作为统计来讲,这是必须的,什么人在什么时间做了什么,这个容易理解,但把这两种指标扩展开来讲,里面还有维度可分,比如时间有维度,可以是年、月、天、小时,从层次上来讲,小时可以反映天、天反映月、月反映年,如果能归并出日报数据,那月报年报自然就能通过日报数据来生成了。事件主体的维度也好理解,比如说事件主体是一个人,也可以是这个人所在的部门、部门所在的公司等等。同样,人的行为可以反映到部门的行为,部门的行为又可以反映到公司的行为,如果网站做区域访问统计,那首先可以做人的访问统计(ip),人的统计再反映到区域的统计,他们之间有层级关系。

        展现型指标比较简单,就是展示一条统计属性额外的一些信息,往往可以通过事件主体来映射生成,比如事件主体是手机号码,报表中同时要展示这个手机号的归属地,那这个归属地就是一个展现型指标。

        统计型指标顾名思义就是通过统计、通过数据分析的来的,是需要我们真正进行采集归并的信息。

        计算型指标,这种类型的数据可能无法或者没必要直接通过数据统计得来,而有可能是某些其他指标通过特定的公式计算出的。

        绝大多数报表需求都跑不出这几种指标类型。除了时间和事件主体是固定的,其他指标都是按需求来走的,各指标独立,没有必然的本质联系(计算型指标可能会有),这些指标中,我们需要采集的只有统计型指标,并且顺带上时间和事件主体。

        那接下来就面临着采集的问题了,我们的原始数据来源还都是数据库,那无非就是从数据库中max、min、avg、sum之类的再group by,我可以一个一个指标去归并再入库,高级一点的话,可以把报表中的一组指标都分析完后再统一入库。所以在后来的程序实现上,我设置了一个归并map,key是时间和事件主体的组合,数据则是统计后的一组指标,所有指标都统计完后再入库。这一点其实就是MapReduce的模式。

        但问题又来了,数据归并完了我往哪入库?我发现自己根本还没有建表。。 但是看看那几十个表,手工建?!。。又回到原始社会了!!

         很多人喜欢偷懒,不喜欢做重复的工作,我也不例外,数据分析能自动做,建表也能由程序来实现,这个时候,把报表开发做成平台的想法开始出现了。

        于是我又分析了一遍需求,发现相同的一些指标会在不同的报表里出现,结果也是一模一样的,软件强调复用,那指标自然也最好能复用,于是我做了如下工作:
        1.把指标的采集sql抽出来,写到配置文件,做成基础指标源
        2.一个综合报表对应写一个配置文件,将一系列基础指标组合进来
        3.开发自动表管理程序,根据配置文件里的一组指标信息,自动创建采集表
        4.开发自动采集程序,根据配置文件里的一组指标信息,自动对原始数据进行采集,并写到对应的表
        5.对于计算型的指标,不需要预先统计,可以在展现的时候按公式计算,在配置文件中预先配好公式即可。
        6.指标都配好了,给每个指标配个表头文字,干脆拿来当展示依据好了。前台一个页面就可以搞定了。配置文件甚至能支持css的控制和js的调用。

        因此一个报表配置实现了多种用途:自动建表的依据、采集分析的依据、前端展现依据。另外一系列的难点和细节不多说了。。。。

        之后报表的开发就相当于只要写配置文件了,报表的开发成本降到了最低,做一个报表只需要一个小时,而且对开发技能的要求很低,再眼花缭乱的报表也都只是配置。

下面总结一下:

1.再复杂的业务逻辑中一定会有共性,要善于抽取共性。数据分析就是典型的共性众多的例子。

2.类似功能的代码永远只需要写一次,拷贝一两次是迫不得已,拷贝两次以上就是愚蠢了,这样的代码永远难以维护。拷贝的初衷是偷懒,实际上是最大的勤勉。

3.共性的东西抽取出来后,配置型开发比编程开发的成本低(在有平台的前提下),容易测试。

4.如果我们做数据中心,用hadoop,每天面临大量的分析需求,那我们有没有可能先做一个开发平台,再在平台上采用配置型开发实现?

5.当然百分百都靠配置型开发也不现实,除非平台特牛逼,各种细节都做到了。

6.开源框架只是解决问题的辅助手段,过分依赖会降低自己的技术水准,在条件许可的情况下,为什么自己的东西不能做成框架而总是要去膜拜别人的东西?我们每个人都要有这样的视野和勇气!


猜你喜欢

转载自huilet.iteye.com/blog/1504820