0%

数据研发开发规范

本文主要包括:

  • 代码开发规范
  • 调度系统使用规范
  • 任务上线流程
  • 数仓分层与命名规范

众所周知,制订交通法规表面上是要限制行车权,实际上是保障公众的人身安全。试想如果没有限速,没有红绿灯,没有靠右行驶条款,谁还敢上路。消防局最主要的工作不是灭火,而是为了不发生火灾建立很多规范。如果发生火灾,说明前面的工作没有做到位。
同理,对于数仓开发来说,开发规范不是消灭开发的创造性、优雅性,而是限制过度个性化,推行相对标准化,以一种普遍认可的方式一起做事。
为此,针对数据研发而言,整理以下开发规范:

  • 代码开发规范
  • 调度系统使用规范
  • 任务上线流程

设计开发规范的长远目标是从有到无,因为人人自觉遵守,规范和谐地融入开发整个流程,规范似乎消失了,但又无处不在。

代码开发规范

数据研发分为离线任务和实时任务,两种任务的开发流程完全不同,故开发规范需要分别定制

离线任务

通用规范

离线数仓的开发,主要是开发sql任务(hive sql/impala sql),针对sql任务,制定以下规范:

  1. 通过编写shell脚本来开发sql任务,一个shell脚本最终只输出一个结果表。中间生成的临时表需要在脚本最后删除
  2. 任务的调度使用DolphinScheduler,每天定时启动
  3. 默认情况下,执行引擎使用Hive-MR,除非对实效性要求很高,可以切换到Impala
  4. 一个hive-cli只能执行一个sql,即一个sql语句不能含有多个;
  5. 脚本统一在自己本地开发,后上传到gitlab,通过DolphinScheduler的代码发布项目(projectDeploy)发布到线上
  6. 如果引用的hive表是分区表,必须指定分区范围,如dt = ‘20220420’
  7. 禁止使用select *
  8. 所有的报表和模型开发必须先出设计再进行开发

注释规范

脚本的开头以及每个sql语句都必须有注视

  1. 注释内容要清晰明了,含义准确,避免歧义
  2. 字段注释紧跟在字段后面
  3. 应对不易理解的分支条件表达式加注释
  4. 对重要的计算应说明其功能
  5. 过长的函数实现,应将其语句按实现的功能分段加以概括性说明
  6. 原则上所有表、字段、任务都需要添加注释,任务有特定的注释规范,见下文任务注释说明

任务注释说明:

# # # # # # -CopyRight# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # -
#   AppName: offline_ods_bm_cust_info
#   Description: 计算售前商机_客户基本信息表,保留历史与最新的数据
#   Source Table:
#        pom.stg_bm_cust_info
#   Output Table:
#        pom.ods_bm_cust_info
#   Version 1.00
#   Language:bash shell
#   CreateDate: 2022/04/14 14:43
#   Author: gujc
#   ITCode: 17405
#   Email: gujc@digiwin.com
# # # # # # Update Log# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#   2022-04-15 修改history分区数据不全的问题
# # # # # # Environment# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
  1. 提供任务名,方便任务创建时任务的获取以及平台中任务查询
  2. 提供创建者、创建日期、功能描述等信息,方便后期维护跟踪
  3. 提供代码变更历史,便于了解代码演进历史及依据
  4. 提供脚本依赖表清单,方便后续任务依赖配置
  5. 提供输出表清单,方便确认是否单个目标表

SQL编写规范

  1. 关键字最好大写,如SELECT、FROM、WHERE等,字段名不做要求
  2. 字段排列要求
  • SELECT 语句选择的字段按每行一个字段方式编排;
  • SELECT 单词后面一个空格后直接跟首个选择的字段,其他字段前”,”点后放字段名
  • 建议每个SELECT的字段后面都有注释,至少在SQL的最外层的SELECT必须要有,并且多个字段的注释对其在同一列上
    SELECT first_name               --第一个名字
          ,last_name                --最后一个名字
          ,salary                   --工资
          ,itcode                   --工号
    FROM employee
    WHERE salary > 35000;
  1. SELECT子句排列要求
    SELECT语句中所用到的FROM、WHERE、GROUP BY、HAVING、JOIN、UNION等子句
  • 换行编写
  • 与相应的SELECT语句对齐
  • WHERE子句下面的逻辑判断符AND、OR等与WHERE左对齐编排
    SELECT cust_id
          ,num
    FROM cust 
    WHERE num >= 100 
      AND num <= 200
       OR proname = 'ORANGE'
    ORDER BY num;
  1. 算术运算符、逻辑运算符前后至少保留一个空格
    SELECT SUM(t1.num * t2.price) / 2 AS total_amt
    FROM fruit_orders t1 
    INNER JOIN fruit_inventory t2 
    ON t1.proid = t2.proid
    WHERE t2.proname = 'ORANGE'
      AND num <= 200;
  2. 一个sql语句最多join 3次,大于3次的,先创建临时表,关联临时表,这样可以使逻辑更清晰,并且方便调查数据问题

其他规范可以参考HQL过程体开发规范

任务脚本案例

数仓脚本开发统一提交到DataWarehose
为了方便编码,让数据研发人员专注于业务逻辑,这里对shell异常捕捉、执行引擎的选择等做了封装,开发人员只要按照固定的模版填充sql即可:

  1. 删除hive临时表:
    V_MSG=" clear Temporary table ${TABLE_TMP_01},write into Temporary table"
    drop_tmp_table -tbn "${TABLE_TMP_01}" -engine hive -env hwCloud
    参数说明:

-tbn:表名
-engine:选择执行引擎,这里目前可以选择hive和impala
-env: 执行环境
hwCloud:华为云
aliCloud:阿里云正式区
aliCloudTest: 阿里云测试区
azureCloud: 微软云

  1. 执行sql语句:
    V_MSG="INSERT OVERWRITE TABLE partition active"
    V_SQL="
    INSERT OVERWRITE TABLE ${TABLE_TMP_01} partition(dp = 'active',end_date = '99991231')
    SELECT activity_id          --活动id
          ,activity_no          --活动编号
          ,activity_name        --活动名称
          ,transaction_times    --交易次数
          ,contact_times        --接触次数
          ,manage_status        --状态
          ,tenantsid            --租户id
    FROM ${TABLE_INPUT_01} -- 因为每天取得数据都是最新的数据,所以,stg表就是最新的数据
    ;
    "
    runsql -sql "${V_SQL}" -msg "${V_MSG}" -engine hive -env hwCloud || return $?
    参数说明:

-sql:要执行的sql语句
-msg:执行sql提示信息
-engine:选择执行引擎,这里目前可以选择hive和impala
-env: 执行环境
hwCloud:华为云
aliCloud:阿里云正式区
aliCloudTest: 阿里云测试区
azureCloud: 微软云
|| return $? : 获取代码执行状态

hive脚本案例可以查看DataWarehose/public/hive_templete.sh
impala脚本案例可以查看DataWarehose/public/impala_templete.sh

调度系统使用规范

  • 工作流按照项目划分,理论上,一个项目的所有任务都在一个工作流内
  • 一个job输出一个结果表,需要配置前置和后置依赖
  • job名称统一按照时间粒度 + 输出结果表名来命名,例如offline_ods_pom_business_work_record,代表离线计算ods_pom_business_work_record
    具体的项目案例,可以参考华为云上的pom项目

任务上线流程

  • 代码在本地开发完成后,需统一提交到DataWarehose
  • 经由管理员codeReview之后合并到master分支
  • 在数据中台-项目管理-projectDeploy,选择相应的job执行代码分发
    数仓项目上线流程