美文网首页Hive Tour
[译]Hive学习指南(五)

[译]Hive学习指南(五)

作者: steanxy | 来源:发表于2017-05-26 11:42 被阅读24次

动态分区插入

前面的示例中,用户必须知道对哪个分区插入数据,并且一条insert语句只能插入一个分区。如果想要加载到多个分区,需要使用多条insert语句,如下:

FROM page_view_stg pvs
INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='US')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'US'
INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='CA')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'CA'
INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='UK')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'UK';

为了将数据加载到特定日期的所有国家分区中,需要为每个国家写insert语句。这样很不方便,你得预先知道国家列表并且创建好分区。如果有一天国家列表改变了,你还得修改insert语句同时得创建对应的分区。这样做效率还低,每个insert语句都会变成MapReduce作业。

动态分区插入(或者多分区插入)就是为解决上述问题设计的,动态分区插入会在扫描输入表时动态决定应该创建和填充哪些分区。这是新加的特性,从0.6.0版本可用。使用动态分区插入,会对输入列的值进行评估,然后决定每行数据应该插入哪个分区。如果分区没有创建,会自动创建分区。使用这个特性只需要写一条insert语句。另外,因为只有一条insert语句,也只有一个对应的MapReduce作业。相比多条inser的情况,这个特性会显著提升性能,减少Hadoop集群的工作负载。

下面是一个加载所有国家分区数据的示例,只用到一条insert语句:

FROM page_view_stg pvs
INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country)
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip, pvs.country

动态分区插入和多条insert语句有一些语法差异:

  • PARTITION中添加了country,但是没有相关值。在这种情况下,country就是动态分区列。dt有值,它是静态分区列。如果是动态分区列,它的值将会来自输入列。目前只允许动态分区列是最后一列,因为分区列的顺序说明了其层次顺序(意味着dt是root分区,country是child分区),不能写成(dt, country='US')。
  • select语句中添加了pvs.country列。这是动态分区列对应的输入列。注意,不需要给静态分区列添加输入列,因为PARTITION语句知道它的值。动态分区值是按照顺序查询的,不是按照名称,并且是select语句的最后一列。

自定义Map/Reduce脚本

用户可以加入已定义的Map/Reduce,这个特性是Hive语言原生支持的。例如,想要运行自动的脚本map_script和reduce_script,用户可以执行以下命令,使用TRANSFORM语句嵌入脚本。

注意,在传给脚本之前,列会被转换为字符串并以TAB分隔,用户脚本的标准输出会被当做以TAB分隔的字符串列。用户脚本的标准错误可以在Hadoop的任务详情页面看到。

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脚本(weekday_mapper.py)

import sys
import datetime
 
for line in sys.stdin:
  line = line.strip()
  userid, unixtime = line.split('\t')
  weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
  print ','.join([userid, str(weekday)])

当然,MAP和REDUCE都是语法糖。内部查询可以写为:

SELECT TRANSFORM(pv_users.userid, pv_users.date) USING 'map_script' AS dt, uid CLUSTER BY dt FROM pv_users;

无模式map/reduce:如果"USING map_script"后没有"AS"语句,Hive假定脚本的输出包含2个部分:key,放在tab之前,value,除key之外其余都放在tab之后。这和指定了"AS key, value"是有区别的,因为如果有多个tab的话,value只会包含了第一个tab和第二个tab之间的部分。

用这种方式,用户可以在不知道map输出模式的情况下迁移老的map/reduce脚本。不过用户还是需要知道reduce输出模式,因为必须与我们要插入的表进行匹配。通常分区列是排序列的前缀,但并不强制。

FROM (
    FROM pv_users
    MAP pv_users.userid, pv_users.date
    USING 'map_script'
    CLUSTER BY key) map_output
 
INSERT OVERWRITE TABLE pv_users_reduced
 
    REDUCE map_output.dt, map_output.uid
    USING 'reduce_script'
    AS date, count;

DISTRIBUTE BY和SORT BY:不指定"cluster by",用户可以指定"distribute by"和"sort by",分区列和排序列可以不同。

    FROM pv_users
    MAP pv_users.userid, pv_users.date
    USING 'map_script'
    AS c1, c2, c3
    DISTRIBUTE BY c2
    SORT BY c2, c1) map_output
 
INSERT OVERWRITE TABLE pv_users_reduced
 
    REDUCE map_output.c1, map_output.c2, map_output.c3
    USING 'reduce_script'
    AS date, count;

Co-Groups

假设我们要用uid列组合actions_video和action_comments表的行,并且将数据发送到自定义的'reduce_script',可以使用如下方式:

FROM (
     FROM (
             FROM action_video av
             SELECT av.uid AS uid, av.id AS id, av.date AS date
 
            UNION ALL
 
             FROM action_comment ac
             SELECT ac.uid AS uid, ac.id AS id, ac.date AS date
     ) union_actions
     SELECT union_actions.uid, union_actions.id, union_actions.date
     CLUSTER BY union_actions.uid) map
 
 INSERT OVERWRITE TABLE actions_reduced
     SELECT TRANSFORM(map.uid, map.id, map.date) USING 'reduce_script' AS (uid, id, reduced_val);

相关文章

  • [译]Hive学习指南(五)

    动态分区插入 前面的示例中,用户必须知道对哪个分区插入数据,并且一条insert语句只能插入一个分区。如果想要加载...

  • [译]Hive学习指南(四)

    查询和插入数据 Hive查询操作参见文档Select,插入操作参见文档Inserting data into Hi...

  • [译]Hive学习指南(一)

    Hive是什么 Hive是基于Apache Hadoop的数据仓库。Hadoop提供了在商用硬件上存储和处理大量数...

  • [译]Hive学习指南(二)

    Hive SQL的能力 Hive's SQL提供了基本SQL操作。这些操作作用于表和分区,具有以下能力: 可使用W...

  • [译]Hive学习指南(三)

    加载数据 有多种方式将数据加载到Hive表中。用户可以创建外部表,指向HDFS中的指定路径。在这种特殊用法中,用户...

  • Vim 自学笔记

    参考内容: Vim实用技巧 [美] Drew Neil 著 杨源 车文隆 译 Vim 学习指南 oschina 翻...

  • Hive | Hive 安装详解

    一、Hive 介绍 二、准备工作 三、Hive下载 四、Hive 安装 五、Hive 启动 一、Hive 介绍 H...

  • iOS智能家居HomeKit学习指南

    iOS智能家居HomeKit学习指南 iOS智能家居HomeKit学习指南

  • Hive开发--Hive--DML(五)

    一、DML 操作 操作手册:https://cwiki.apache.org/confluence/display...

  • 五. hive介绍

    介绍 由Facebook开源,最初用于解决海量结构化的日志数据统计问题 构建在Hadoop之上的数据库 Hive定...

网友评论

    本文标题:[译]Hive学习指南(五)

    本文链接:https://www.haomeiwen.com/subject/vwyvxxtx.html