前言
今天无意在在某群里,看到一个很复杂的SQL脚本,join很多,子查询很多,union很多,case when也很多。然后就让我们负责分析师脚本管理的同事给我看了下我们分析师的脚本,我发现随便一个竟然都超了三四百行。这脚本维护起来应该是个噩梦。如果要让一个东西好维护,好管理,那一定需要项目化,如何项目化一个脚本呢?
这个其实很像前端,原先前端就是一个html页面,有html,javascript,css等,然后一开始大家就是在一个页面写完所有逻辑,后面出现了Vue,react等框架,把前端单一页面开发项目化了。我们知道,表现层的东西是多变的,难以复用的,比如html代码片段就比较难以复用。同样的,SQL具有很强的表达能力,以及比编程语言更低的使用门槛,但是复用难度也是比较大的。不过你愿意,总是可以的。
设计
针对前面的问题,我设计了一套项目体系,可以让分析师以较为结构化和项目化的思维去完成一个脚本的编写。当然,这个是运行在我们内部的Skone系统之上的,底层的DSl语法则是MLSQL,引擎是StreamingPro。
项目目录结构为如下:
这是A分析师的一个项目目录,叫analyser。 里面分成了四个子目录。
- function 可以复用脚本片段,如果分析师还会写python,则包含udf函数。
- entity_tables 分析师使用到的落地中间表。
- virtual_tables 分析师使用到的虚拟中间表。
- job 分析师任务脚本集合,一个job就是完成一个功能点,比如出一张报表。
function
我们先来看function目录:
里面包含两种类型的的可复用脚本。第一个是SQL代码片。比如上图里的,我们经常会反复用一个case when,这个时候就可以抽象成一个代码片段。其实说白了就是做了个名字映射。
使用时,可以这样:
另外一个就是如果分析师会一些脚本,那么可以整理自己一些常用的函数库。
使用时可以这样:
virtual_tables
我们知道,在分析师实际写脚本的时,往往为了完成一个结果,会需要产生大量的中间表,不同的job可能会有依赖同一批中间表。virtual_tables目录使得分析师可以统一管理自己的经常使用的中间表。
这张图例,就是产生了一张表明为 vistor_count_from_three_channes的表。
job
job 目录则是分析师真正完成工作的地方。通常,分析师会include function/virtual_tables里函数或者表在最终job里使用,比如:
这个过程,分析师导入了votes表,shares表,然后union 了他们,最后追加到hive表里。
总结
通过这套体系,强化了分析师们的抽象和复用能力,也简化了脚本复杂度。分析师自己就很方便构建常用的虚拟表集合,对于经常用到的一些处理逻辑,也可以进行很好的封装。而如果分析师熟悉python脚本,也能更好的进行自主开发。
我们还可以让分析师把项目一键发送给数仓工程师,让他们完成最后的上线过程。