数仓建设指南
数据模型架构规范
数据层次的划分
- ODS:Operational Data Store,操作数据层,在结构上其与源系统的增量或者全量数据基本保持一致。它相当于一个数据准备区,同时又承担着基础数据的记录以及历史变化。其主要作用是把基础数据引入到MaxCompute。
- CDM:Common Data Model,公共维度模型层,又细分为DWD和DWS。它的主要作用是完成数据加工与整合、建立一致性的维度、构建可复用的面向分析和统计的明细事实表以及汇总公共粒度的指标。
- DWD:Data Warehouse Detail,明细数据层。
- DWS:Data Warehouse Summary,汇总数据层。
- ADS:Application Data Service,应用数据层。
具体仓库的分层情况需要结合业务场景、数据场景、系统场景进行综合考虑。
数据分类架构
该数据分类架构在ODS层分为三部分:数据准备区、离线数据和准实时数据区。在进入到CDM层后,由以下几部分组成:
- 公共维度层:基于维度建模理念思想,建立整个企业的一致性维度。
- 明细粒度事实层:以业务过程为建模驱动,基于每个具体业务过程的特点,构建最细粒度的明细层事实表。您可以结合企业的数据使用特点,将明细事实表的某些重要维度属性字段做适当的冗余,即宽表化处理。
- 公共汇总粒度事实层:以分析的主题对象为建模驱动,基于上层的应用和产品的指标需求,构建公共粒度的汇总指标事实表,以宽表化手段来物理化模型。
数据处理流程架构
数据划分及命名空间约定
请根据业务划分数据并约定命名,建议针对业务名称结合数据层次约定相关命名的英文缩写,这样可以给后续数据开发过程中,对项目空间、表、字段等命名做为重要参照。
- 按业务划分:命名时按主要的业务划分,以指导物理模型的划分原则、命名原则及使用的ODS project。
- 按数据域划分:命名时按照CDM层的数据进行数据域划分,以便有效地对数据进行管理,以及指导数据表的命名。例如,“交易”数据的英文缩写可定义为“trd”。
- 按业务过程划分:当一个数据域由多个业务过程组成时,命名时可以按业务流程划分。业务过程是从数据分析角度看客观存在的或者抽象的业务行为动作。例如,交易数据域中的“退款”这个业务过程的英文缩写可约定命名为“rfd_ent”。
数据模型
模型是对现实事物的反映和抽象,能帮助我们更好地了解客观世界。数据模型定义了数据之间关系和结构,使得我们可以有规律地获取想要的数据。例如,在一个超市里,商品的布局都有特定的规范,商品摆放的位置是按照消费者的购买习惯以及人流走向进行摆放的。
-
数据模型的作用
数据模型是在业务需求分析之后,数据仓库工作开始时的第一步。良好的数据模型可以帮助我们更好地存储数据,更有效率地获取数据,保证数据间的一致性。
-
模型设计的基本原则
-
高内聚和低耦合
一个逻辑和物理模型由哪些记录和字段组成,应该遵循最基本的软件设计方法论中的高内聚和低耦合原则。主要从数据业务特性和访问特性两个角度来考虑:将业务相近或者相关的数据、粒度相同数据设计为一个逻辑或者物理模型;将高概率同时访问的数据放一起,将低概率同时访问的数据分开存储。
-
核心模型与扩展模型分离
建立核心模型与扩展模型体系,核心模型包括的字段支持常用核心的业务,扩展模型包括的字段支持个性化或是少量应用的需要。在必须让核心模型与扩展模型做关联时,不能让扩展字段过度侵入核心模型,以免破坏了核心模型的架构简洁性与可维护性。
-
公共处理逻辑下沉及单一
底层公用的处理逻辑应该在数据调度依赖的底层进行封装与实现,不要让公用的处理逻辑暴露给应用层实现,不要让公共逻辑在多处同时存在。
-
成本与性能平衡
适当的数据冗余可换取查询和刷新性能,不宜过度冗余与数据复制。
-
数据可回滚
处理逻辑不变,在不同时间多次运行数据的结果需确定不变。
-
一致性
相同的字段在不同表中的字段名必须相同。
-
命名清晰可理解
表命名规范需清晰、一致,表命名需易于下游的理解和使用。
-
说明
- 一个模型无法满足所有的需求。
- 需合理选择数据模型的建模方式。
- 通常,设计顺序依次为:概念模型->逻辑模型->物理模型。
公共规范
层次调用约定
应用层应优先调用公共层数据,必须存在中间层CDM数据,不允许应用层跨过中间层CDM从ODS层重复加工数据。
中间层CDM需要积极了解应用层数据的建设需求,将公用的数据沉淀到公共层,为其他层提供数据服务。应用层需要积极配合中间层CDM持续改造公共层。必须避免出现过度的引用ODS层、不合理的数据复制以及子集合冗余。
- ODS层数据不能被应用层任务引用,中间层CDM不能有沉淀的ODS层数据,必须通过CDM层的视图访问。CDM层视图必须使用调度程序进行封装,保持视图的可维护性与可管理性。
- CDM层任务的深度不宜过大(建议不超过10层)。
- 原则上一个计算刷新任务只允许一个输出表。
- 如果多个任务刷新输出一个表(不同任务插入不同的分区),需要建立一个依赖多个刷新任务的虚拟任务,通常下游应该依赖此虚拟任务。
- CDM汇总层应优先调用CDM明细层。在调用可累加类指标计算时,CDM汇总层尽量优先调用已经产出的粗粒度汇总层,以避免大量汇总直接从海量的明细数据层计算。
- CDM明细层累计快照事实表优先调用CDM事务型事实表,以保持数据的一致性产出。
- 避免应用层过度引用和依赖CDM层明细数据,需要针对性地建设好CDM公共汇总层。
项目分配
按实际需求分配不同的ODS和CDM项目。一个ODS层项目对应一个CDM项目。例如:
- ODS层项目,按业务部门的粒度建立。
- CDM层项目,按业务部门的粒度建立。
- ADS层项目,按应用的粒度建立。
一个项目的划分结构如下图所示。
项目命名规范
- ODS层项目名称以
ods
为后缀,例如xx_ods
。 - 中间层CDM项目名称以
cdm
为后缀,例如xx_cdm
。 - 应用层项目中,数据报表、数据分析等应用名称以
bi
为后缀,例如xx_bi
;而数据产品等应用名称以app
为后缀,例如sycm_app
。
数据类型规范
ODS层的数据类型应基于源系统数据类型转换。例如,源数据为MySQL时的转换规则如下。
MySQL数据类型 | Hive数据类型 |
---|---|
TINYINT | INT |
SMALLINT/MEDIUMINT | INT |
INTEGER | INT |
BIGINT | BIGINT |
FLOAT | FLOAT |
DOUBLE | DOUBLE |
DECIMAL | DECIMAL |
CHAR/VARCHAR | STRING |
LONGTEXT/TEXT | STRING |
DATE/TIMESTAMP/TIME/YEAR | STRING |
DATETIME | DATETIME |
CDM数据公共层如果是引用ODS层数据,则默认使用ODS层字段的数据类型。其衍生加工数据字段按以下标准执行:
- 金额类及其它小数点数据使用DOUBLE类型。
- 字符类数据使用STRING类型。
- ID类和整形数值使用BIGINT类型。
- 时间类型数据使用STRING类型(如果有特殊的格式要求,可以选择性使用DATETIME类型)。
- 状态使用STRING类型。
公共字段定义规范
- 数据统计日期的分区字段按以下标准:
- 按天分区:ds(YYYYMMDD)。
- 按小时分区:hh(00~23)。
- 按分钟:mi(00~59)。
- is_{业务}:表示布尔型数据字段。以Y和N表示,不允许出现空值域。
- 原则上不需要冗余分区字段。
数据冗余
一个表做宽表冗余维度属性时,应该遵循以下建议准则:
- 冗余字段与表中其它字段高频率(大于3个下游应用SQL)同时访问。
- 冗余字段的引入不应造成其本身的刷新完成时间产生过多后延。
- 公共层数据不允许字段重复率大于60%的相同粒度数据表冗余,可以选择在原表基础上拓宽或者在下游应用中通过JOIN方式实现。
数据拆分
数据的水平和垂直拆分是按照访问热度分布和数据表非空数据值、零数据值在行列二维空间上分布情况进行划分的。
- 在物理上划分核心模型和扩展模型,将其字段进行垂直划分。
- 将访问相关度较高的列在一个表存储,将访问相关度较低的字段分开存储。
- 将经常用到的Where条件按记录行进行水平切分或者冗余。水平切分可以考虑二级分区手段,以避免多余的数据复制与冗余。
- 将出现大量空值和零值的统计汇总表,依据其空值和零值分布状况可以做适当的水平和垂直切分,以减少存储和下游的扫描数据量。
空值处理原则
- 汇总类指标的空值:空值处理,填充为零,当前基于列存储的压缩技术不会由于填充大量空值导致存储成本上升。
- 维度属性值为空:在汇总到对应维度上时,对于无法对应的统计事实,记录行会填充为-99(未知),对应维表会出现一条-99(未知)的记录。
ODS层设计规范
命名规范
-
表命名规范
表命名规则:{层次}{源系统表名}{保留位/delta与否}。
- 增量数据:{project_name}.s{源系统表名}delta。
- 全量数据:{project_name}.s{源系统表名}。
- ODS ETL过程的临时表:{project_name}.tmp{临时表所在过程的输出表}{从0开始的序号}。
- 按小时同步的增量表:{project_name}.s{源系统表名}{delta}_{hh}。
- 按小时同步的全量表:{project_name}.s{源系统表名}{hh}。
- 当不同源系统同步到同一个Project下的表命名冲突时,您需要给同步较晚的表名加上源系统的dbname以解决冲突。
-
字段命名规范
- 字段默认使用源系统的字段名。
- 字段名与关键字冲突时,在源字段名后加上col,即源字段名col。
-
同步任务命名规范
-
任务名:
{源系统表名}[delta]。
说明
同一Project下异库同名表的任务名为**{源系统表名}{tddl的appname}[_delta]**。
-
任务的输出名称,即输出表的名称,需要与数据存储及生命周期管理规范保持一致。
-
数据存储及生命周期管理规范
数据表类型 | 存储方式 | 最长存储保留策略 |
---|---|---|
ODS流水型全量表 | 按天分区 | 不可再生情况下,永久保存。日志(数据量非常大,例如一天数据量大于100 GB)数据保留24个月。自主设置是否保留历史月初数据。自主设置是否保留特殊日期数据。 |
ODS镜像型全量表 | 按天分区 | 重要的业务表及需要保留历史的表视情况保存。ODS全量表的默认生命周期为2天,支持通过ds=max_pt(tablename) 方式访问数据。 |
ODS增量表 | 按天分区 | 有对应全量表,最多保留最近14天分区数据。无对应全量表,需要永久保留数据。 |
ODS ETL过程临时表 | 按天分区 | 最多保留最近7天分区。 |
DBSync非去重数据 | 按天分区 | 由应用通过中间层保留历史数据,默认ODS层不保留历史数据。 |
数据质量规范
- 每个ODS全量表必须配置唯一性字段标识。
- 每个ODS全量表必须有注释。
- 每个ODS全量表必须监控分区空数据。
- 建议对重要表的重要枚举类型字段进行枚举值变化及枚举值分布监控。
- 建议对ODS表的数据量及数据记录数设置周同环比监控,如果周同环比无变化,表示源系统已迁移或下线。
CDM公共维度层设计规范
设计准则
-
一致性维度规范
公共层的维度表中相同维度属性在不同物理表中的字段名称、数据类型、数据内容必须保持一致。除了以下情况:
- 在不同的实际物理表中,如果由于维度角色的差异,需要使用其他的名称,其他名称也必须是规范的维度属性的别名。例如,定义一个标准的会员ID时,如果在一个表中,分别要表示买家ID,卖家ID,那么设计规范阶段就预先对会员ID分别定义买家ID和卖家ID。
- 如果由于历史原因,在暂时不一致的情况下,必须在规范的维度定义一个标准维度属性,不同的物理名也必须是来自标准维度属性的别名。
-
维度的组合与拆分
- 组合原则
- 将维度所描述业务相关性强的字段在一个物理维表实现。相关性强是指经常需要一起查询或进行报表展现、两个维度属性间是否存在天然的关系等。例如,商品基本属性和所属品牌。
- 无相关性的维度可以适当考虑杂项维度(例如交易),可以构建一个交易杂项维度收集交易的特殊标记属性、业务分类等信息。也可以将杂项维度退化在事实表中处理,不过容易造成事实表相对庞大,加工处理较为复杂。
- 所谓的行为维度是经过汇总计算的指标,在下游的应用使用时将其当维度处理。如果有需要,度量指标可以作为行为维度冗余到维度表中。
- 拆分与冗余
- 对于维度属性过多,涉及源较多的维度表(例如会员表),可以做适当拆分:
- 拆分为核心表和扩展表。核心表相对字段较少,刷新产出时间较早,优先使用。扩展表字段较多,且可以冗余核心表部分字段,刷新产出时间较晚,适合数据分析人员使用。
- 根据维度属性的业务不相关性,将相关度不大的维度属性拆分为多个物理表存储。
- 数据记录数较大的维度表(例如商品表),可以适当冗余一些子集合,以减少下游扫描数据量:
- 可以根据当天是否有行为,产出一个有活跃行为的相关维表,以减少应用的数据扫描量。
- 可根据所属业务扫描数据范围大小的不同,进行适当子集合冗余。
- 对于维度属性过多,涉及源较多的维度表(例如会员表),可以做适当拆分:
- 组合原则
表命名规范
命名规则:{project_name}.dim{业务/pub}{维度定义}[_{自定义命名标签}],其中的pub与具体业务无关,各个业务部都可以共用,例如时间维度。
数据存储及生命周期管理规范
CDM公共维度层的表的类型为维度表,存储方式为按天分区。
模型设计者根据自身业务需求设置表的生命周期管理。您可依据3个月内的最大需要访问的跨度设置保留策略,具体计算方式如下:
- 当3个月内的最大访问跨度小于或等于4天时,建议将保留天数设为7天。
- 当3个月内的最大访问跨度小于或等于12天时,建议将保留天数设为15天。
- 当3个月内的最大访问跨度小于或等于30天时, 建议将保留天数设为33天。
- 当3个月内的最大访问跨度小于或等于90天时,建议将保留天数设为93天。
- 当3个月内的最大访问跨度小于或等于180天时, 建议将保留天数设为183天。
- 当3个月内的最大访问跨度小于或等于365天时,建议将保留天数设为368天。
CDM明细层设计规范
表命名规范
命名规则:{project_name}.dwd{业务缩写/pub}{数据域缩写}{业务过程缩写}[{自定义表命名标签缩写}]{刷新周期标识}{单分区增量全量标识}。
命名说明:
- pub表示数据包括多个业务的数据。
- 单分区增量全量标识:i表示增量,f表示全量。
数据存储及生命周期管理规范
CDM明细层的表的类型为事实表,存储方式为按天分区。
事务型事实表一般永久保存。周期快照型事实表根据业务需求设置生命周期管理。您可依据3个月内的最大需要访问的跨度设置保留策略,具体计算方式如下:
- 当3个月内的最大访问跨度小于或等于4天时,建议将保留天数设为7天。
- 当3个月内的最大访问跨度小于或等于12天时,建议将保留天数设为15天。
- 当3个月内的最大访问跨度小于或等于30天时, 建议将保留天数设为33天。
- 当3个月内的最大访问跨度小于或等于90天时,建议将保留天数设为93天。
- 当3个月内的最大访问跨度小于或等于180天时, 建议将保留天数设为183天。
- 当3个月内的最大访问跨度小于或等于365天时,建议将保留天数设为368天。
事务型事实表设计准则
事务型事实表主要用于分析行为与追踪事件。事务事实表获取业务过程中的事件或者行为细节,然后通过事实与维度之间关联,可以非常方便地统计各种事件相关的度量,例如浏览UV,搜索次数等等。
- 基于数据应用需求的分析设计事务型事实表,如果下游存在较大的针对某个业务过程事件的分析指标需求,可以考虑基于某一个事件过程构建事务型事实表。
- 事务型事实表一般选用事件发生日期或时间作为分区字段,这种分区方式可以方便下游的作业数据扫描执行分区裁剪。
- 明细层事实表的冗余子集的原则能有利于降低上层数据访问的IO开销。
- 明细层事实表维度退化到事实表原则能有利于减少上层数据访问的JOIN成本。
周期快照型事实表
周期快照型事实表主要用于分析状态型或者存量型事实。快照是指以预定的时间间隔来采样状态度量。
累计快照事实表
累计快照事实表是基于多个业务过程联合分析从而构建的事实表,如采购单的流转环节等。
累计快照事实表主要用于分析事件之间的时间间隔与周期。例如,用交易的支付与发货之间的间隔,来分析发货速度,或在支付和退款环节分析支付退款率等等。
累计快照事实表同时也可以用于帮助分析一些少量的、且对刷新时间不是非常敏感的指标统计。例如,在当前事务型事实表不支持,且只有少量的统计指标时,需要分析交易的关闭和发货,就可以基于累计快照事实表进行计算。
CDM汇总层设计规范
命名规范
命名规则:{project_name}.dws{业务缩写/pub}{数据域缩写}{数据粒度缩写}[{自定义表命名标签缩写}]{统计时间周期范围缩写}{刷新周期标识}{单分区增量全量标识}。
命名说明:
-
在默认情况下,离线计算应该包括最近一天(1d)、最近N天(nd)和历史截至当天(td)三个表。
如果nd表的字段过多,需要拆分时,只允许以一个统计周期单元作为原子拆分,即一个统计周期拆分一个表。例如,最近7天(1w)拆分一个表,不允许拆分出来的一个表存储多个统计周期。
-
对于{刷新周期标识}和{单分区增量全量标识}在汇总层不做强制要求。单分区增量全量标识:i表示增量,f表示全量。
-
对于小时表不管是按天刷新还是按小时刷新,都用_hh来表示。
-
对于分钟表不管是按天刷新还是按小时刷新,都用_mm来表示。
数据存储及生命周期管理规范
CDM汇总层的表的类型为事实表,存储方式为按天分区。
事务型事实表一般会永久保存。周期快照型事实表根据业务需求设置生命周期管理。您可依据3个月内的最大需要访问的跨度设置保留策略,具体计算方式如下:
- 当3个月内的最大访问跨度小于或等于4天时,建议将保留天数设为7天。
- 当3个月内的最大访问跨度小于或等于12天时,建议将保留天数设为15天。
- 当3个月内的最大访问跨度小于或等于30天时,建议将保留天数设为33天。
- 当3个月内的最大访问跨度小于或等于90天时,建议将保留天数设为93天。
- 当3个月内的最大访问跨度小于或等于180天时,建议将保留天数设为183天。
- 当3个月内的最大访问跨度小于或等于365天时,建议将保留天数设为368天。
CDM接口数据层设计规范
接口数据层将不同数据域的汇总数据预关联在一个物理表,开放给应用使用,以减少应用层多次重复JOIN的成本开销,CDM接口数据层更适用于实时计算。
命名规则:{project_name}.dwi{业务 BU 缩写/pub}{数据域/hbd}{数据粒度缩写}[{自定义表命名标签缩写}]_{统计时间周期范围缩写}。统计时间周期范围和数据域说明如下:
-
关于统计时间周期范围缩写,默认情况下,离线计算包括最近一天(1d)、 最近N天(nd)和历史截至当天(td)三个表。
说明
如果出现
nd
的表字段过多,需要拆分时,只允许以一个统计周期单元作为原子拆分,即一个统计周期拆分一个表,例如最近7天(1week)拆分一个表,不允许拆分出一个表存储多个统计周期。 -
如果一个汇总表出现混合多个数据域时,表名称中需要使用hbd(hybird 缩写)进行标识,这种情况当前只用于准实时情况,离线计算不建议跨数据域存储数据。
其他命名规范
视图命名规范
视图命名规范如下:
- ODS层直接以视图形式开放到CDM层:{project_name}.dwd_{ODS 表名}。
- 中间层视图命名规范:遵循中间层命名规范,且加上后缀{project_name}.{dws/dwd}_{中间层表命名规范要求}。
脚本间可复用的中间表命名规范
因为所有表都是以分区表形式存在的,因此中间表不设置命名规范,全部以正式表方式处理。
临时表命名规范
不同场景下临时表命名规范不同:
- 测试、数据探查、临时取数等场景下产生的临时表命名规范为:{project_name}.tmp{工号/操作人名标识}{产出表表名}_{n}。
- 脚本内临时表命名规范:{project_name}.tmp{产出表表名}{n}。
下线表命名规范
一般生产任务下线后,不急于立马下线表,一般继续存放3个月,修改表名做标注,3个月后再下线表。下线表统一后缀 _retireyyyymmdd,生产任务下线后的表重命名为YYYYMMDD。三个月后需要与表拥有者确认是否能删除。
数据开发规范
视图相关规范
-
视图设计规范
-
视图的命名规范与表保持一致。
-
建议创建独立的刷新任务以产生视图,创建视图的脚本如下。
create or replace view ***;
-
工作流节点设计规范
-
工作流节点类型和命名
-
工作流节点的输出表命名规范
projectname.tablename
-
工作流节点命名规范
节点类型 命名规范 备注 虚拟节点 vt_{虚拟节点含义} 任务根节点。 同步节点导入任务 imp{表名}[{源库标示}] 如果多个源库存在表名重复的情况,可以增加源库标识的后缀。 同步节点导出任务 exp{表名}[{目标库标示}] 如果存在多个目标库,可以增加目标库标识的后缀。 数据处理节点 {输出表名} 多个目标表输出任务时,选定一个主要表名作为节点名。多个任务插入同一张表的不同分区时,可以建一个虚拟目标表任务。 Shell节点 sh_{脚本命名} 不涉及 MapReduce节点 mr_{脚本命名} 不涉及
-
-
资源文件命名规范
资源名称需有后缀表示资源类型,例如**.JAVA**、.PY、.SH等。
-
任务设计规范
SQL任务:
- 每个SQL任务至少有一个输出表。
- 脚本需支持重跑,例如使用INSERT OVERWRITE等语句,以便在系统错误时,重跑任务不会出现重复数据等脏数据。
- 代码如果有时间或日期参数,需采用类似
{bdp.system.cyctime}
的调度参数,以方便调试。 - 自定义参数,采用**${变量名}**在发布任务时进行配置。变量名即为调度参数。
编码规范
-
编写原则
- 代码行清晰、整齐,具有一定的可观赏性。
- 代码编写要充分考虑执行速度最优原则。
- 代码行整体层次分明、结构化强。
- 代码中应有必要的注释以增强代码的可读性。
- 规范要求非强制性地约束代码开发人员的代码编写行为。在实际应用中,只要不违反常规要求,允许存在可理解的偏差。
-
基本要求
- 代码中应用到的所有SQL关键字、保留字都需使用全大写或小写,例如select/SELECT、from/FROM、where/WHERE、and/AND、or/OR、union/UNION、insert/INSERT、delete/DELETE、group/GROUP、having/HAVING、count/COUNT等。不能使用大小写混合的方式,例如Select或seLECT等方式。
- 代码中应用到的除关键字、保留字之外的代码,都要求使用小写。
- 四个空格为一个缩进量,所有的缩进均为一个缩进量的整数倍。
- 禁止使用
SELECT *
操作,所有操作必须明确指定列名。 - 通常要求对应的括号在同一列上。
-
数据类型
- 表字段类型应尽量与业务系统一致。
- 不推荐大量使用STRING类型,以免数据加工环节的数据质量问题无法及时暴露。
- 在对精度要求极其严格的场景下请使用DECIMAL类型。
- 关于货币类型
- 中国货币单位统一为人民币元,国际货币单位统一为美元。
- 除非模型有特殊说明,否则中间层金额相关的数据不执行任何四舍五入操作,以避免后续的汇总计算中出现不同口径的汇总结果不一致的情况。
-
编码规范
进行数据开发时,在数据开发工作台上进行代码编辑的规范。
-
代码头部
代码头部添加主题、功能描述、作者、日期等信息。并提供修改日志及标题栏的功能,以便后续修改人员添加修改记录。每一行不能超过80个字符。
针对不同的任务类型提供了不同的代码头部模板,例如,SQL类型任务头部模板默认为如下。
--sql --********************************************************************-- --author:${author} --create time:${createTime} --********************************************************************--
-
字段排列要求
- SELECT语句选择的字段按每行一个字段方式编排。
- SELECT单字后面一个缩进量后应直接跟首个选择的字段,即字段离首起二个缩进量。
- 其它字段前导二个缩进量再跟一个逗号(,)后放置字段名。
- 两个字段之间的逗号(,)分割符紧跟在第二个字段的前面。
- AS语句应与相应的字段在同一行,多个字段的AS建议尽量对齐在同一列上。
-
SELECT子句排列要求
SELECT语句中所用到的FROM、WHERE、GROUP BY、HAVING、ORDER BY、JOIN、UNION等子句,需遵循如下要求:
- 换行编写。
- 与相应的SELECT语句左对齐编排。
- 子句后续的代码离子句首字母二个缩进量起编写。
- WHERE子句下的逻辑判断符AND、OR等与WHERE左对齐编排。
- 超过两个缩进量长度的子句加一空格后编写后续代码。例如ORDER BY、GROUP BY等。
-
运算符前后间隔要求
算术运算符、逻辑运算符的前后要保留一个空格。
-
CASE语句的编写
SELECT语句中对字段值进行判断取值的操作将用到CASE语句,正确的编排CASE语句对加强代码行的可读性也是很关键的一部分。对CASE语句编排的约定如下:
- WHEN子句在CASE语句的同一行并缩进一个缩进量后开始编写。
- 每个WHEN子句单独一行编写,如果语句较长可换行编写。
- CASE语句必须包含ELSE子语,ELSE子句与WHEN子句对齐。
-
子查询嵌套编写规范
在数据仓库系统ETL开发中经常需要用到子查询嵌套,因此代码的分层编排变得非常重要。
-
表别名定义约定
建议对所有的表加上别名。一旦在SELECT语句中对表定义了别名,在整个语句中对此表的引用都必须以别名替代。考虑到编写代码的便捷性,约定别名尽量简洁,同时避免使用关键字。 表别名定义约定如下:
- 表别名采用简单字符命名。
- 多层次的嵌套子查询,在别名之前要体现层次关系。SQL语句别名或分层的命名,从第一层次至第四层次,分别用P、S、U、D表示,取意为Part,Segment,Unit,Detail。也可用a、b、c、d来表示第一层次到第四层次。对于同一层次的多个子句,可以在字母后加1、2、3、4区分。
- 必要时,为表别名添加注释。
-
SQL注释
- 每条SQL语句均应添加注释说明。
- 每条SQL语句的注释单独成行并置于语句前面。
- 字段注释紧跟在字段后面。
- 应为不易理解的分支条件表达式添加注释。
- 应说明重要计算的功能。
- 过长的函数实现,应将其语句按实现的功能分段加以概括性说明。
- 常量及变量注释时,必须注释被保存值的含义,按需注释合法的取值范围 。
-