# 什么是Transform
** 会使用Python做数据处理的小伙伴一定使用过自己定义的函数去加工处理数据。在hive中的自定义函数支持Transform和UDF。UDF是将java代码打包上传,如果你不想或不会写java代码也可以,那就用到了Transform,写一个脚本,通过脚本(Python、shell)来处理数据。**
** transform的原理可以追溯到Hadoop的Streaming架构,Hadoop Streaming框架,最大的好处是,让任何语言编写的map, reduce程序能够在hadoop集群上运行;map/reduce程序只要遵循从标准输入stdin读,写出到标准输出stdout即可。其次,容易进行单机调试,通过管道前后相接的方式就可以模拟streaming, 在本地完成map/reduce程序的调试。**
** 那么transform本质上也是一种Streaming,Hive用户可以使用Transform关键字在字符数据流中插入自己定义的map和reduce程序。在使用Transform的时候,默认情况下,在数据输入到用户自定义的脚本之前,列将转换为STRING并由TAB分隔;**
** 类似地,所有NULL值都将转换为文本字符串\N,以便区分NULL值和空字符串。用户脚本的标准输出将被视为TAB分隔的STRING列,任何仅包含\N的单元格将被重新解释为NULL,然后生成的STRIG列将以通常的方式转换为表声明中指定的数据类型。用户脚本可以将调试信息输出为标准错误,该错误将显示在hadoop的任务详细信息页面上。**
**本位采用Python这个在数据科学应用较多的语言去写脚本,Python如何获取Hive传入的数据呢?Python中是有标准输入这样的东东的,它在sys模块中。我们获取数据的代码可以这样写:**
```
import sys
for line in sys.stdin:
pass # 后续写我们的处理逻辑就可以了
```
**Hive会自动把数据传过来,各个列之间由TAB间隔,也就是\t。**
**引用官方示例说明使用方法:**
**这是一个类似streaming的功能,但是可以更方便的访问Hive中的数据,也可以把SQL语句和自写脚本整合在一起运行。**
**简单分析 **[官网](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Transform#LanguageManualTransform-TRANSFORMExamples) 上的一个例子
```
FROM (
FROM pv_users
SELECT TRANSFORM(pv_users.userid, pv_users.date)
USING 'map_script'
AS dt, uid
CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
SELECT TRANSFORM(map_output.dt, map_output.uid)
USING 'reduce_script'
AS date, count;
```
**这段代码的大致工作流程描述如下:**
`map_script` 作为mapper, `reduce_script` 作为reducer。将 `pv_users` 表中的 `userid` , `date`两列作为mapper的输入字段,处理后的输出的前两个字段分别命名为 `dt` , `uid` ,并按照 `dt` 字段作partition和sort送给reduce阶段处理。reducer的输入字段为 `dt` 和 `uid` ,输出处理后的前两个字段,并命名为 `date` , `count` ,写入到 `pv_users_reduced` 表中。
**这里有几个细节:**
* **mapper和reducer用到的script可以是任何可执行文件。 ****注意** 如果用到的是本地文件,应当在语句开始前用 `ADD FILE` 或 `ADD FILES` 将文件加入进来
* **mapper和reducer的输入输出都是以TAB为分隔符**
* **如果 **`USING ‘script’` 语句后面没有 `AS` ,则Hive默认 `script` 的输出中第一个TAB之前的字段为key,后面的部分全部为value。若指定了 `AS` ,则严格按照 `AS` 后面的字段数输出,例如`AS dt, uid` ,则输出前两个字段并忽略后面的字段。此外, `AS` 语句可以指定数据类型,如`AS (date STRING, count INT)` 。默认都是 `string` 类型。
* `CLUSTER BY` 关键字是 `DISTRIBUTE BY` 和 `SORT BY` 的简写,这两者可以认为对应与Hadoop的partition和sort过程。如果partition和sort的key是不同的,可以使用 `DISTRIBUTE BY` 和 `SORT BY` 分别指定。
* **MAP 和 REDUCE 关键字是 SELECT TRANSFORM 关键字的别名,原文中给出了上面等价代**
```
FROM (
FROM pv_users
MAP pv_users.userid, pv_users.date
USING 'map_script'
AS dt, uid
CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
REDUCE map_output.dt, map_output.uid
USING 'reduce_script'
AS date, count;
```
**因此,原文中特别提醒, MAP并没有强制产生一个map过程的作用,REDUCE同理。只是为了阅读更清晰。**
**转自:**[https://blog.csdn.net/u012802702/article/details/70199368](https://blog.csdn.net/u012802702/article/details/70199368)
评论(0)
暂无数据