hive从查询中获取数据插入到表或动态分区
Hive的insert语句能够从查询语句中获取数据,并同时将数据Load到目标表中。现在假定有一个已有数据的表staged_employees(雇员信息全量表),所属国家cnty和所属州st是该表的两个属性,我们做个试验将该表中的数据查询出来插入到另一个表employees中。
如果把OVERWRITE关键字删掉,或者替换成INTO,则hive会追加而不是替代原分区或原表中的数据,这个特性在Hive v0.8.0之后才支持。
当数据已经存在于hdfs上但不是我们想要的格式的时候,当进行的计算需要分好多步骤有必要存储中间数据的时候,或者原数据没有分区、有很多无效列需要过滤的时候,可以使用insert..select句型来完成这一转换过程。
由于一个国家有很多个省份,如果想根据(国家country,地区partition)两个维度对数据进行分区的话,这条SQL语句的执行个数应该等于地区的数目,比如中国有23个省就要对该SQL语句执行23次。因此hive对这个SQL语句进行了改造,只需要扫描一次原表就可以生成不同的输出(多路输出)。比如下面的SQL语句扫描了一次原始数据表,但是同时生成了3个省份的结果数据:
- FROM staged_employees se
- INSERT OVERWRITE TABLE employees
- PARTITION (country = '中国', state = '河北省')
- SELECT * WHERE se.cnty = '中国' AND se.st = '河北省'
- INSERT OVERWRITE TABLE employees
- PARTITION (country = '中国', state = '陕西省')
- SELECT * WHERE se.cnty = '中国' AND se.st = '陕西省'
- INSERT OVERWRITE TABLE employees
- PARTITION (country = '中国', state = '河南省')
- SELECT * WHERE se.cnty = 'US' AND se.st = '河南省';
通过缩进可以很清楚的看到,我们扫描了一次staged_employees表但是执行了3次不同的insert语句,这条大SQL语句是这么执行的:先通过from staged_employees表获取一条记录,然后执行每一个select子句,如果select子句验证通过则执行相应的insert语句。注意这里的三条select子句是完全独立执行的,并不是if .. then .. else的关系,这就意味着这3条select子句在某种情况下可能同时通过where检测。
通过这种结构,原始表的数据能被拆分到目标表的不同partition中去。
如果原表的一条记录满足于其中一个给定的select .. where .. 子句,则该记录将被写到目标表的固定分区中。其实更进一步,每条Insert语句能将数据写到不同的数据表中,不管这个表是否分区都一样。
于是,就像一个过滤器一样,原表的一些数据被写到了很多输出地址,而剩下的数据会被丢弃。
当然,你也可以混用Insert overwrite和insert into两种不同的方法写出数据。
向动态分区插入数据
但是问题还是没有解决,中国有23个省,那么我们就需要写23个insert into .. select ..where子句,这非常不现实。于是hive的一种叫做动态分区的特性就出现了,它能够根据select出来的参数自动推断将数据插入到那个分区中去。本文上面的两种SQL语句设定分区的方式都叫做静态分区插入。
将上一个SQL语句进行改动,会得到以下简洁的新SQL语句:
hive先获取select的最后两个位置的se.cnty和se.st参数值,然后将这两个值填写到Insert语句partition中的两个country和state变量中,即动态分区是通过位置来对应分区值的。原始表select出来的值和输出partition的值的关系仅仅是通过位置来确定的,和名字并没有关系,比如这里se.cnty和county的名称完全没有关系。
上面的这条SQL语句是对两个分区同时进行了动态设定,如果staged_employees表中有100个国家,每个国家有100个地区,那么该SQL语句自动对每个国家和地区建立相应的partition并插入数据,如果用手写的话不现实。
只要位置正确,你可以混用动态分区和静态分区值设定,比如下面这个例子,你可以静态指定一个country值,但是state值采用动态的方法设定:
注意:静态分区值必须在动态分区值的前面!
使用hive动态分区的参数设定
动态分区功能默认是关闭的,而当它是打开状态时,默认会工作在“strict”模式下,这种模式下要求至少指定一个静态分区的值。这样做是为了防止设计了大量partition的糟糕情况,举个例子你使用时间戳来进行分区,竟然每一秒钟都产生一个分区!还有其他的一些属性设定用来限制类似的情况出现,如下表所示:
名称 | 默认值 | 描述 |
hive.exec.dynamic.partition | false | 设置为true用于打开动态分区功能 |
hive.exec.dynamic.partition.mode | strict | 设置为nonstrict能够让所有的分区都动态被设定,否则的话至少需要指定一个分区值 |
hive.exec.max.dynamic.partitions.pernode | 100 | 能被每个mapper或者reducer创建的最大动态分区的数目,如果一个mappre或者reducer试图创建多余这个值的动态分区数目,会引发错误 |
hive.exec.max.dynamic.partitions | +1000 | 被一条带有动态分区的SQL语句所能创建的动态分区总量,如果超出限制会报出错误 |
hive.exec.max.created.files | 100000 | 全局能被创建文件数目的最大值,专门有一个hadoop计数器来跟踪该值,如果超出会报错 |
举个例子,使用全动态分区的SQL语句序列如下所示,需要先设定一些必要的参数才可以:
总结
使用from .. insert.. select ..where结构能够从一个数据表中抽取数据,将结果插入到不同的表和分区中,而使用动态分区能够让hive根据select最末几个位置的值自动设定目标分区的值,使用动态分区需要设定一些hive运行参数。
转自:http://www.crazyant.net/1197.html
hive从查询中获取数据插入到表或动态分区的更多相关文章
- sql 根据指定条件获取一个字段批量获取数据插入另外一张表字段中+MD5加密
/****** Object: StoredProcedure [dbo].[getSplitValue] Script Date: 03/13/2014 13:58:12 ******/ SET A ...
- mysql结构相同的三张表查询一条记录\将一张表中的数据插入另外一张表
将一张表中的数据插入另外一张表 1.两张表结构相同 insert into 表1名称 select * from 表2名称 2.两张结构不相同的表 insert into 表1名称(列名1,列名2,列 ...
- SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...
- MySQL将表a中查询的数据插入到表b中
MySQL将表a中查询的数据插入到表b中 假设表b存在 insert into b select * from a; 假设表b不存在 create table b as select * from a ...
- oracle将查询到的数据插入到数据库的表中
一.Oracle数据库中,把一张表的查询结果直接生成并导入一张新表中. 例如:现有只有A表,查询A表,并且把结果导入B表中.使用如下SQL语句: create table b as selec ...
- Hive扩展功能(三)--使用UDF函数将Hive中的数据插入MySQL中
软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...
- 通过myclipse建立一个简单的Hibernate项目(PS:在单元测试中实现数据的向表的插入)
Hibernate的主要功能及用法: Ⅰ.Hibernate封装了JDBC,使Java程序员能够以面向对象的思想对数据库进行操作 Ⅱ.Hibernate可以应用于EJB的J2EE架构,完成数据的持久化 ...
- Thymeleaf+SpringMVC,如何从模板中获取数据
Thymeleaf+SpringMVC,如何从模板中获取数据 在一个典型的SpringMVC应用中,带@Controller注解的类负责准备数据模型Map的数据和选择一个视图进行渲染.这个模型Map对 ...
- 哪种方式更适合在React中获取数据?
作者:Dmitri Pavlutin 译者:小维FE 原文:dmitripavlutin.com 国外文章,笔者采用意译的方式,以保证文章的可读性. 当执行像数据获取这样的I/O操作时,你必须发起获取 ...
随机推荐
- Hexo+yilia添加helper-live2d插件宠物动画,很好玩的哦~~
个人主页:https://www.yuehan.online 现在博客:www.wangyurui.top 安装模块: 博客根目录选择cmd命令窗口或者git bash 输入以下代码,安装插件 操作: ...
- boost之定时器和io_service
1.定时器的使用,sleep是等待线程,asio封装了操作系统的异步系统调用select,epoll. io_servie 实现了一个任务队列,这里的任务就是void(void)的函数.Io_serv ...
- C# 函数4
//数据库 public class GF_DA { /// <summary> /// 执行SQL语句 sConnStr 连接字符串,sq ...
- 中间件 WSGI
冒泡程序 array = [1, 2, 5, 3, 6, 8, 4] for i in range(len(array) - 1, 0, -1): print i for j in range(0, ...
- 在英文Windows操作系统上使用SQL Server Management Studio(SSMS)导入Excel 97-2003文件时报错:Failure creating file
今天在公司服务器上使用SQL Server Management Studio(SSMS)导入Excel 97-2003文件(.xls)时报错: Failure creating file. (Mic ...
- [不常用] - CSRF(跨站点请求伪造)
CSRF,Cross Site Request Forgery,即跨站点请求伪造. 这种攻击是指,在用户正常登录系统以后,攻击者诱使用户访问一些非法链接,以执行一些非法操作. 比如:如果删除用户操 ...
- 主攻ASP.NET.4.5.1 MVC5.0之重生:空地搭建一个包含 Ninject框架 项目
1.创建一个空白解决方案 2.添加一个类库 名称为XXX.Domain 3.添加一个ASP.MVC 名称为XXX.WebUI 4.选着空模版,勾选MVC核心引用 5.添加单元测试项目XXX.UntiT ...
- 使用Java实现八种基本排序
插入排序.选择排序.冒泡排序.希尔排序.堆排序.快速排序.归并排序.基数排序 import java.util.ArrayList; import java.util.List; /** * 排序算法 ...
- INSPIRED启示录 读书笔记 - 第12章 产品探索
软件项目可以划分为两个阶段 探索产品阶段:弄清楚要开发什么产品(定义正确的产品) 在探索产品的阶段,产品经理负责分析各种创意,广泛收集用户需求,了解如何运用新技术,拿出产品原型并加以测试 从全局视角思 ...
- juniper设置共享上网(注意事项)
注意:出去的 策略 ,勾上 NAT 选项