构建 hive 时间维表

2023-11-01 02:04
文章标签 构建 时间 hive 维表

本文主要是介绍构建 hive 时间维表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

众所周知 hive 的时间处理异常繁琐且在一些涉及日期的统计场景中会写较长的 sql,例如:周累计、周环比等;本文将使用维表的形式降低时间处理的复杂度,提前计算好标准时间字符串未来可能需要转换的形式。

一、表设计

结合业务场景常用的时间字符串格式为 yyyyMMdd,因此我们将这种格式字段作为维表的关联键,用来派生剩下的字段,例如 yyyy-MM-dd、yyyy/MM/dd、yyyy、MM、dd 以及令人头疼的周(w),因此当前版本的时间维表 DDL 如下

create table dim_xxx.dim_dateformat
(dt          string comment '日期,yyyymmdd',dt_format1  string comment '日期,yyyy-mm-dd',dt_format2  string comment '日期,yyyy/mm/dd',dt_year     string comment '所在年份',dt_month    string comment '所在月份',dt_day      string comment '所在日',dt_week_str string comment '星期(英文)',dt_week_num string comment '星期(数字)',dt_abs_week bigint comment '绝对周,从 19700101 为第一周',dt_rel_week string comment '相对周,从本年的第一个周一为第一周'
) comment '日期维表'stored as parquet;

需要解释一下 dt_abs_week 和 dt_rel_week 字段,该字段用于提升周累计、周环比的计算效率。dt_abs_week 绝对周是约定 19700101 为第一周,后续每遇到一个周一加一;dt_rel_week 主要用来对外展示,例如:

  1. 截止昨日周累计:获取通过 dt 获取昨日所在的 dt_abs_week 或 dt_rel_week,从而可以当前周的 dt 范围,根据 dt 关联业务表即可
  2. 周环比:获取通过 dt 获取昨日所在的 dt_abs_week - 1 即可获取环比的所在周,再结合 dt_week_num 可以灵活控制环比整周或环比上周的对应星期

二、填充数据

这里使用 python 生成 csv 并 load 进去即可(这种方式最简单,对比过使用 sql 来实现),因为生产环境 hive 表的存储格式往往不是 textfile,例如博主所在公司所用的存储格式就是 parquet,遵循一切从简的原则,创建同 schema 的 textfile 表(一切从简,注释都不写)

create table dim_xxx.dim_dateformat_load
(dt          string,dt_format1  string,dt_format2  string,dt_year     string,dt_month    string,dt_day      string,dt_week_str string,dt_week_num string,dt_abs_week string,dt_rel_week string
)row format delimited fields terminated by ','stored as textfile;

下面的重点是 python 如何实现,直接上代码

import datetime
import csv# 定义日期范围
start_date = datetime.date(1970, 1, 1)
end_date = datetime.date(2500, 12, 31)with open(file='dim_dateformat.csv', mode='w', encoding='utf8', newline='') as f:writer = csv.writer(f)# 循环遍历current_date = start_date# 初始绝对周abs_week_num = 1# 初始相对周rel_week_num = 1rel_year = 1970display_year_of_week = '1970-1'while current_date <= end_date:# 各种时间格式format1 = current_date.strftime("%Y%m%d")format2 = current_date.strftime("%Y-%m-%d")format3 = current_date.strftime("%Y/%m/%d")# 年、月、日、星期year = current_date.yearmonth = current_date.strftime("%m")day = current_date.strftime("%d")day_of_week1 = current_date.strftime("%A")day_of_week2 = current_date.strftime("%w")day_of_week2 = day_of_week2 if day_of_week2 != '0' else '7'if day_of_week2 == '1':abs_week_num += 1# 计算相对周rel_week_num += 1if rel_year != year:rel_year = yearrel_week_num = 1display_year_of_week = str(rel_year) + '-' + str(rel_week_num)# 写入 csvwriter.writerow([format1, format2, format3, year, month, day, day_of_week1, day_of_week2, abs_week_num,display_year_of_week])# ++current_date += datetime.timedelta(days=1)

解释一下相对周和绝对周的计算方式即可

  1. 初始化 abs_week_num、rel_week_num 为 1,rel_year 为 1970
  2. 如果是周一,abs_week_num 加 1;rel_week_num 加 1 转第 3 步。否则转第 4 步
  3. 如果年份不等于 rel_year 则将当前年份赋值给 rel_year 并重置 rel_week_num 为 1
  4. 写入文件

对于绝对周初始为 1 后逢周一进一即可,对于相对周,对于周的部分也是逢周一进一,若跨年则年份加一后重置周的计数

之后将得到的 dim_dateformat.csv 文件 load 进 dim_dateformat_load 并执行下面 sql

insert overwrite table dim_dateformat
select * from dim_dateformat_load

结果如下
在这里插入图片描述

接下来就可以拿着这张维表尽情玩耍吧

这篇关于构建 hive 时间维表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/319714

相关文章

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Java中字符串转时间与时间转字符串的操作详解

《Java中字符串转时间与时间转字符串的操作详解》Java的java.time包提供了强大的日期和时间处理功能,通过DateTimeFormatter可以轻松地在日期时间对象和字符串之间进行转换,下面... 目录一、字符串转时间(一)使用预定义格式(二)自定义格式二、时间转字符串(一)使用预定义格式(二)自

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码

《Java中Date、LocalDate、LocalDateTime、LocalTime、时间戳之间的相互转换代码》:本文主要介绍Java中日期时间转换的多种方法,包括将Date转换为LocalD... 目录一、Date转LocalDateTime二、Date转LocalDate三、LocalDateTim

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n