构建 hive 时间维表

2023-11-01 02:30
文章标签 构建 时间 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/319837

相关文章

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

java时区时间转为UTC的代码示例和详细解释

《java时区时间转为UTC的代码示例和详细解释》作为一名经验丰富的开发者,我经常被问到如何将Java中的时间转换为UTC时间,:本文主要介绍java时区时间转为UTC的代码示例和详细解释,文中通... 目录前言步骤一:导入必要的Java包步骤二:获取指定时区的时间步骤三:将指定时区的时间转换为UTC时间步

Docker多阶段镜像构建与缓存利用性能优化实践指南

《Docker多阶段镜像构建与缓存利用性能优化实践指南》这篇文章将从原理层面深入解析Docker多阶段构建与缓存机制,结合实际项目示例,说明如何有效利用构建缓存,组织镜像层次,最大化提升构建速度并减少... 目录一、技术背景与应用场景二、核心原理深入分析三、关键 dockerfile 解读3.1 Docke

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

C# LiteDB处理时间序列数据的高性能解决方案

《C#LiteDB处理时间序列数据的高性能解决方案》LiteDB作为.NET生态下的轻量级嵌入式NoSQL数据库,一直是时间序列处理的优选方案,本文将为大家大家简单介绍一下LiteDB处理时间序列数... 目录为什么选择LiteDB处理时间序列数据第一章:LiteDB时间序列数据模型设计1.1 核心设计原则

Python利用PySpark和Kafka实现流处理引擎构建指南

《Python利用PySpark和Kafka实现流处理引擎构建指南》本文将深入解剖基于Python的实时处理黄金组合:Kafka(分布式消息队列)与PySpark(分布式计算引擎)的化学反应,并构建一... 目录引言:数据洪流时代的生存法则第一章 Kafka:数据世界的中央神经系统消息引擎核心设计哲学高吞吐

MySQL按时间维度对亿级数据表进行平滑分表

《MySQL按时间维度对亿级数据表进行平滑分表》本文将以一个真实的4亿数据表分表案例为基础,详细介绍如何在不影响线上业务的情况下,完成按时间维度分表的完整过程,感兴趣的小伙伴可以了解一下... 目录引言一、为什么我们需要分表1.1 单表数据量过大的问题1.2 分表方案选型二、分表前的准备工作2.1 数据评估