数仓日期维表之设计、数据与维护
前言:
从业近10年,在每家公司都能见到日期维表,不论数仓、报表系统做得如何,数据是否规范,日期维表是简单还是复杂,终归是有一个日期维表的。
恰逢近期在BI工程师的要求下,准备了一个附带每年节假日的日期维表,自己从日期维表的字段设计,到使用python获取数据,到最终数据导入到Hive中,全部实操了一遍,刚好趁热打铁记录一下。
特色:
本篇会考虑到非常多的对日期维表的字段需求,除了上面提到的节假日调休字段,还会考虑到节气、农历、天干地支等等数据。
除了记录字段设计,以及如何从python获取数据,还会提示哪些数据需要在何时进行维护。
实操:
一、设计
将日期维表粗分成三个段位:
1、做左表关联用的工具表,预先设置好前后200年的日期字段
date_format1 string COMMENT '日期,yyyy-MM-dd',
date_format2 string COMMENT '日期,yyyyMMdd',
日期维表只需要有最最最必要字段:日期(yyyymmdd)或者(yyyy-mm-dd),很多时候已经很解决问题了,在做一些简单报表的场景下,当考虑到数据不一定会铺到所有的日期,而通常需要每日日期都需要有一条数据时才会想到用日期维表。通常只有此需求的时候,日期维表只需用最简单的即可。
2、日期做成yyyymmdd和yyyy-mm-dd格式,统一周、季、月标签,预先计算好第几周、月第几天等指标
常规字段:
date_format1 string COMMENT '日期,yyyy-MM-dd',
date_format2 string COMMENT '日期,yyyyMMdd',
date_timestamp timestamp COMMENT '日期时间戳,yyyy-MM-dd HH:mm:ss',
year_of_date string COMMENT '日期所属年份,yyyy',
start_date_of_year string COMMENT '日期所属年份第一天,yyyy-MM-dd',
day_of_year bigint COMMENT '当年的第几天',
week_of_year bigint COMMENT '当年的第几周',
month_of_date string COMMENT '日期所属月份,yyyy-MM',
start_date_of_month string COMMENT '日期所属月份第一天,yyyy-MM-dd',
end_date_of_month string COMMENT '日期所属月份最后一天,yyyy-MM-dd',
day_of_month bigint COMMENT '当月的第几天',
week_of_month bigint COMMENT '当月的第几周',
quarter_of_date string COMMENT '日期对应季度,e.g.Q1,Q2,Q3,Q4',
week_of_date string COMMENT '星期,e.g.星期一,星期二,...',
start_date_of_week string COMMENT '日期所属星期第一天,yyyy-MM-dd',
end_date_of_week string COMMENT '日期所属星期最后一天,yyyy-MM-dd',
day_of_week bigint COMMENT '当周的第几天',
is_weekend bigint COMMENT '是否是周末:1-是,0-否',
is_weekday bigint COMMENT '是否工作日:1-是,0-否',
设计到这种程度的日期维表,一半的原因是需要统一处理一些日期标签,避免各自写处理逻辑而产生不一致的错误。而另一半是通过尽可能多的设计字段,来规范用日期加工的标签字段,这样的日期维表更像是指引,很多用不上,但是如果想用的时候会第一时间想到在日期维表里找或添加,这在数仓日期标签规范上有很大的作用。多数的日期维表也大致做到这个程度(日期的年季月周日等可以描述日期的各种标签)足以应付各种场景。
3、有明确的业务需求,如考勤数据需要判断节假日和调休、各种节气、天干地支信息会用在营销、推广等场景
以下的字段设计均按照2中的字段做扩展,按主题分为节假日调休、农历、天干地支三部分。
3.1、节假日调休
date_format1 string COMMENT '日期,yyyy-MM-dd',
date_format2 string COMMENT '日期,yyyyMMdd',
date_timestamp timestamp COMMENT '日期时间戳,yyyy-MM-dd HH:mm:ss',
year_of_date string COMMENT '日期所属年份,yyyy',
start_date_of_year string COMMENT '日期所属年份第一天,yyyy-MM-dd',
day_of_year bigint COMMENT '当年的第几天',
week_of_year bigint COMMENT '当年的第几周',
month_of_date string COMMENT '日期所属月份,yyyy-MM',
start_date_of_month string COMMENT '日期所属月份第一天,yyyy-MM-dd',
end_date_of_month string COMMENT '日期所属月份最后一天,yyyy-MM-dd',
day_of_month bigint COMMENT '当月的第几天',
week_of_month bigint COMMENT '当月的第几周',
quarter_of_date string COMMENT '日期对应季度,e.g.Q1,Q2,Q3,Q4',
week_of_date string COMMENT '星期,e.g.星期一,星期二,...',
start_date_of_week string COMMENT '日期所属星期第一天,yyyy-MM-dd',
end_date_of_week string COMMENT '日期所属星期最后一天,yyyy-MM-dd',
day_of_week bigint COMMENT '当周的第几天',
is_weekend bigint COMMENT '是否是周末:1-是,0-否',
is_weekday bigint COMMENT '是否工作日:1-是,0-否',
is_holiday bigint COMMENT '是否节假日: 1-是 0-否',
is_in_lieu bigint COMMENT '是否调休: 1-是 0-否',
is_weekend_in_lieu bigint COMMENT '是否周末调休: 1-是 0-否',
is_weekday_in_lieu bigint COMMENT '是否工作日调休: 1-是 0-否',
is_work bigint COMMENT '是否工作: 1-是 0-否',
is_rest bigint COMMENT '是否休息: 1-是 0-否',
holiday_desc string COMMENT '节假日描述',
etl_time timestamp COMMENT '数据处理时间: yyyy-MM-dd hh:mm:ss'
此分割线下待补充--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
农历
天干地支
数据
用到的数据包:datetime|chinese_calendar|zhdate|sxtwl|lunardate
维护
维护核心要关注的就是上述用到的几个python包的更新,尤其是关于中国节假日的包,每年11月底左右,国务院会公布第二年的节假日安排,届时chinese_calendar会新增第二年的节假日及对应调休的数据。
浙公网安备 33010602011771号