HSQL转换成MapReduce过程

本文分享了Hive如何让开发者通过SQL语句操作HDFS系统中文件内容的心得。介绍了Hive整体架构中compiler部分将HiveSQL转换成MapReduce任务的基本步骤,包括SQL解析、语义分析、逻辑计划等,还提及可查看Hive SQL编译后的执行计划。

hive的库、表等数据实际是hdfs系统中的目录和文件,让开发者可以通过sql语句, 像操作关系数据库一样操作文件内容, 比如执行查询,统计,插入等操作。一直很好奇hive是如何做到这些的。通过参考网上几篇不错的文档, 有点小心得分享出来。主要的参考链接
http://tech.meituan.com/hive-sql-to-mapreduce.html
http://www.slideshare.net/recruitcojp/internal-hive
注明:本文的图片借用slideshare内容。

hive的整体架构图如下所示, compiler部分负责把HiveSQL转换成MapReduce任务。

在这里插入图片描述
基本转换步骤
hiveSQL转换成MapReduce的执行计划包括如下几个步骤:
HiveSQL ->AST(抽象语法树) -> QB(查询块) ->OperatorTree(操作树)->优化后的操作树->mapreduce任务树->优化后的mapreduce任务树
在这里插入图片描述

SQL Parser:Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象 语法树AST Tree;
Semantic Analyzer:遍历AST Tree,抽象出查询的基本组成单元QueryBlock;
Logical plan:遍历QueryBlock,翻译为执行操作树OperatorTree;
Logical plan optimizer: 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量;
Physical plan:遍历OperatorTree,翻译为MapReduce任务;
Logical plan optimizer:物理层优化器进行MapReduce任务的变换,生成最终的执行计划;

step1: SQL Parser
如下图所示, sql语句可以解析为三个部分
AST中第一个部分对应SQL语句中FROM access_log_hbase a JOIN product_hbase p ON (a.prono=p.prono)。
insert overwrite table对应第二部分。
select a.user, a.prono, p.maker, p.price对应第三部分。

在这里插入图片描述

step2: Semantic Analyzer
这个步骤把AST转换成基本的查询块QB,如下图所示
QB的对象包括如下属性:
aliasToTabs:保存表格别名的信息
aliasToSubq:保存子查询的信息
qbm:保存每个输入表的元信息,比如表在HDFS上的路径,保存表数据的文件格式等

QBParseInfo对象包括如下属性:
joinExpr: 保存TOK_JOIN节点信息
destToxx:保存输出和各个操作的ASTNode节点的对应关系。

在这里插入图片描述
如下图中, 表格别名a, p保存到aliasTotabs, 分别对应“access_log_hbase", " product_hbase"。
TOK_JOIN信息保存到ParseInfo对象:joinExpr
在这里插入图片描述
下图所示,TOK_DESTINATION节点保存到nameToDest属性中。
在这里插入图片描述
下图所示,TOK_SELECT节点保存到nameToDest属性中。
在这里插入图片描述

step3:Logical Plan
该步骤是把查询块QB转换操作树。
操作树基本的操作符包括TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator。
TableScanOperator: 扫描数据表中数据,从原表中取数据。
JoinOperator完成Join操作。
FilterOperator完成过滤操作, 对应sql里面的where语句功能
ReduceSinkOperator:标志着Hive Map阶段的结束, Reduce阶段的开始。
SelectOperator:reduce阶段输出select中的列
FileSinkOperator: 生成结果数据到输出文件。

从两个输入表格中读入数据, 用operator树表示为两个TableScanOperator节点

在这里插入图片描述
Join放在reduce阶段执行, 执行join节点前,加入两个ReduceSinkOperator节点,表示当前map阶段结束, 进入到reduce阶段
在这里插入图片描述
selectoperator节点,从reduce节点获取select指定的列值。
在这里插入图片描述
nameToDest ASTNode节点,转换为FileSinkOperator节点, 把结果写入到目标文件。
在这里插入图片描述
通过上面几个转换步骤, 最终生成的logical计划树。
在这里插入图片描述

logical plan tree还可以通过logical plan optimizer进一步优化, 优化完成的逻辑优化树还有转换成物理执行计划和物理执行计划优化。本文不做详细介绍, 后续有时间再补充。

PS: 查看hive sql编译后的执行计划
hive> explain select * from tablename;

参考文档:
http://tech.meituan.com/hive-sql-to-mapreduce.html
http://www.slideshare.net/recruitcojp/internal-hive
http://lxw1234.com/archives/2015/09/476.htm

作者:wujustin
链接:https://www.jianshu.com/p/660fd157c5eb
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

<think>我们有一个整数20250715,需要将其转换为日期时间类型(datetime)。在HSQL(HyperSQL)中,我们可以使用内置的日期函数来处理这种转换。 整数20250715表示一个日期,格式为YYYYMMDD。我们可以将其拆分为年、月、日部分,然后使用这些部分来构造一个日期。 在HSQL中,我们可以使用`TO_DATE`函数将字符串转换为日期,或者使用`PARSEDATETIME`函数(如果可用)。但是,由于我们有一个整数,首先需要将其转换为字符串,然后按照格式解析。 步骤: 1. 将整数转换为字符串,例如:`CAST(20250715 AS VARCHAR(8))` 2. 使用`TO_DATE`函数将字符串转换为日期,指定格式为'YYYYMMDD' 3. 如果需要日期时间类型(datetime),在HSQL中,日期类型和日期时间类型是分开的。通常,日期类型只包含年月日,而时间类型包含时分秒。如果我们只需要日期部分,那么转换为日期类型即可。如果需要包含时间(比如00:00:00),那么我们可以将其视为时间戳(timestamp)类型。 注意:HSQL中有两种日期时间类型:DATE(只有日期)和TIMESTAMP(日期和时间)。根据需求,这里我们可能需要DATE或TIMESTAMP。 假设我们需要的是TIMESTAMP类型(即包含时间部分),我们可以将转换后的日期加上时间部分,或者直接使用`TO_TIMESTAMP`函数。 但是,HSQL的`TO_DATE`函数只返回日期类型(没有时间),而`TO_TIMESTAMP`函数可以返回时间戳。因此,我们可以使用`TO_TIMESTAMP`并指定格式,将字符串转换为时间戳(时间部分默认为00:00:00)。 具体步骤: - 将整数转换为字符串,并确保是8位(不足8位前面补0,但这里20250715是8位,所以不需要补)。 - 使用`TO_TIMESTAMP`函数,并指定格式为'yyyyMMdd'。 示例SQL: ```sql SELECT TO_TIMESTAMP(CAST(20250715 AS VARCHAR(8)), 'yyyyMMdd') FROM your_table; ``` 或者,如果我们只需要日期(不包含时间),可以使用: ```sql SELECT TO_DATE(CAST(20250715 AS VARCHAR(8)), 'yyyyMMdd') FROM your_table; ``` 注意:在HSQL中,日期格式的字符串中,年份使用小写`yyyy`,月份使用大写`MM`,日期使用大写`dd`。 另外,如果整数可能不足8位(比如2024123表示2024年1月23日,但只有7位),我们需要先将其格式化为8位字符串(前面补0)。但题目中给的是20250715,是8位,所以可以直接转换。 如果整数是7位,我们可以使用`LPAD`函数来补0,例如:`LPAD(CAST(2024123 AS VARCHAR(7)), 8, '0')`,但注意HSQL的`LPAD`函数用法。 但是,题目要求转换整数20250715,所以我们可以直接使用。 因此,对于整数20250715,我们可以这样转换: ```sql SELECT TO_TIMESTAMP(CAST(20250715 AS VARCHAR(8)), 'yyyyMMdd') AS datetime_value; ``` 这将返回一个时间戳类型,值为2025-07-15 00:00:00。 如果我们需要在HSQL中创建一个表或者更新表等操作中使用这个转换,也可以类似处理。 注意:在HSQL 2.x中,函数名可能是`PARSEDATETIME`,但根据HSQL文档,`TO_TIMESTAMP`和`TO_DATE`是支持的。具体可以参考HSQL文档。 由于HSQL版本可能有差异,如果上述函数不可用,我们还可以使用日期构造器:`DATE`和`TIMESTAMP`。 例如,使用`TIMESTAMP`函数: ```sql SELECT TIMESTAMP(2025-07-15) ... ``` 但是这样需要分别提取年、月、日,比较麻烦。 所以,推荐使用`TO_TIMESTAMP`或`TO_DATE`。 总结:将整数20250715转换为日期时间类型(时间戳)的方法是: 1. 将整数转换为字符串(8位)。 2. 使用`TO_TIMESTAMP`函数,并指定格式'yyyyMMdd'。 生成相关问题: 1. 在HSQL中如何将日期时间类型转换为整数(格式为YYYYMMDD)? 2. HSQL中日期时间函数有哪些常用方法? 3. 在HSQL中如何处理日期时间格式的转换错误?</think>在 HSQL 中,将整数 `20250715`(格式为 `YYYYMMDD`)转换为日期时间类型(`DATETIME` 或 `TIMESTAMP`),可通过以下步骤实现: ### 方法 1:使用 `TO_DATE` 函数(推荐) ```sql SELECT TO_DATE(CAST(20250715 AS VARCHAR(8)), 'YYYYMMDD') AS converted_date FROM your_table; ``` **说明**: 1. `CAST(20250715 AS VARCHAR(8))`:将整数转换为 8 位字符串 `'20250715'`。 2. `TO_DATE(..., 'YYYYMMDD')`:按格式 `YYYYMMDD` 解析字符串为 `DATE` 类型(HSQL 会自动扩展为时间戳 `TIMESTAMP`,时间部分为 `00:00:00`)。 3. 结果示例:`2025-07-15 00:00:00.000`。 ### 方法 2:使用 `PARSEDATETIME` 函数(HSQL 2.x+) ```sql SELECT PARSEDATETIME(CAST(20250715 AS VARCHAR(8)), 'yyyyMMdd') AS converted_timestamp FROM your_table; ``` **说明**: - 直接生成 `TIMESTAMP` 类型,时间部分为 `00:00:00`。 - 格式参数需用小写(`yyyyMMdd`),与 `TO_DATE` 不同。 ### 方法 3:拼接字符串并转换(通用) ```sql SELECT CAST( SUBSTRING(CAST(20250715 AS VARCHAR(8)), 1, 4) || '-' || SUBSTRING(CAST(20250715 AS VARCHAR(8)), 5, 2) || '-' || SUBSTRING(CAST(20250715 AS VARCHAR(8)), 7, 2) AS TIMESTAMP ) AS converted_timestamp FROM your_table; ``` **说明**: 1. 通过 `SUBSTRING` 分割年、月、日(如 `2025-07-15`)。 2. 用 `||` 拼接为 ISO 日期格式字符串。 3. `CAST(... AS TIMESTAMP)` 转换为时间戳类型。 --- ### 关键点总结 1. **类型转换**: 需先将整数转为字符串(`CAST(value AS VARCHAR(8))`)。 2. **日期格式**: - `TO_DATE` 使用 `YYYYMMDD`(大写) - `PARSEDATETIME` 使用 `yyyyMMdd`(小写) 3. **结果类型**: `DATE` 类型不含时间部分,`TIMESTAMP` 含时间(默认为 `00:00:00`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值