《Hive权威指南》第五章:数据操作

1.向管理表中装载数据

LOAD DATA LOCAL INPATH '${env:HOME}/california-employees'
OVERWRITE INTO TABLE employees
PARTITION (country='US', state='CA');

如果分区目录不存在的话,这个命令会先创建分区目录,然后再将数据拷贝到该目录下。

如果使用了LOCAL关键字,那么这个路径应该为本地文件系统路径。数据将会被拷贝到目标位置。如果省略掉LOCAL关键字,那么这个路径应该是分布式文件系统中的路径。这种情况下,数据是从这个路径转移到目标位置的。

注意:这种方式是移动的,Hive要求源文件和目标文件以及目录应该在同一个文件系统中。例如,用户不可以使用LOAD DATA语句将数据从一个集群的HDFS中转载(转移)到另一个集群的HDFS中

如果用户使用了OVERWRITE关键字,那么目标文件夹中之前存在的数据将会被先删除掉,如果没有就会增量导入到目标文件夹中,而不会删除之前的文件。

实际上如果没有使用OVERWRITE关键字,而目标文件夹下已经存在同名的文件时,会保留之前的文件并且会重命名新文件为“之前文件名_序列号”。

上述特性是Hive v0.9.0+才用,在这个版本之前,如果没有使用OVERWRITE,也会覆盖目标文件夹下的同名文件,造成数据丢失的bug

若使用PARTITION子句,而且用户还必须为每个分区的键指定一个值。

对于使用了INPATH子句中使用的文件路径还有一个限制,那就是这个路径下不可以包含任何文件夹

Hive并不会验证用户装载的数据和表模式是否匹配。然后Hive会验证文件格式是否和表结构定义的一致。例如,定义存储格式为SEQUENCEFILE,那么转载进去的文件也应该是sequencefile格式才行。

2.通过查询语句向表中插入数据

INSERT OVERWRITE TABLE employees
PARTITION(country = 'US', state = 'OR')
SELECT * FROM staged_employees se
WHERE se.cnty = 'US' AND se.st = 'OR';

如果表staged_employees非常大,而且用户需要对65个州都执行这些语句,那么就意味这需要扫描staged_employees表65次!Hive提供了另一种INSERT语法,可以只扫描一次输入数据,然后按多种方式划分。如下:

FROM staged_employees se
INSERT OVERWRITE TABLE employees
	PARTITION(country = 'US', state = 'OR')
	SELECT * WHERE se.cnty = 'US' AND se.st = 'OR'
INSERT OVERWRITE TABLE employees
	PARTITION(country = 'US', state = 'OR')
	SELECT * WHERE se.cnty = 'US' AND se.st = 'CA'
INSERT OVERWRITE TABLE employees
	PARTITION(country = 'US', state = 'OR')
	SELECT * WHERE se.cnty = 'US' AND se.st = 'IL'

动态分区插入

请看如下例子:

INSERT OVERWRITE TABLE employees
PARTITION(country, state)
SELECT ..., se.cnty, se.st
FROM staged_employees se;

Hive根据SELECT语句中最后两列来确定分区字段country和state的值。

同样用户,也可以混合使用动态和静态分区,如下例子中指定了country字段的值为静态的US,而分区字段state是动态值。

INSERT OVERWRITE TABLE employees
PARTITION(country = 'US', state)
SELECT ..., se.cnty, se.st
FROM staged_employees se
WHERE se.cnty = 'US';

注意:静态分区键必须出现在动态分区键之前

动态分区功能默认情况下没有开启。开启后,默认是以**“严格”模式**执行的,这种模式下要求至少有一列分区字段是静态的。这有助于阻止设计错误导致查询产生大量的分区。

其他相关属性值用于资源利用:

属性名缺省值描述
hive.exec.dynamic.partitionfalse设置为true,表示开启动态分区功能
hive.exec.dynamic.partition.modestrict设置为nostrict,表示允许所有分区都是动态的
hive.exec.max.dynamic.partitions.pernode100每个mapper或reducer可以创建的最大动态分区个数。如果某个mapper或reducer尝试创建大于这个值的分区的话则会抛出一个致命错误信息
hive.exec.max.dynamic.partitions+1000一个动态分区创建语句可以创建的最大动态分区个数。如果超过这个值则会抛出一个致命错误信息
hive.exec.max.created.files100000全局可以创建的最大文件个数。有一个Hadoop计数器会跟踪记录创建了多少个文件,如果超过这个值则会抛出一个致命错误信息

3.单个查询语句中创建表并加载数据

CREATE TABLE ca_employees
AS SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';

一般这个功能用于从一个大宽表中选取部分需要的数据集

这个功能不能用于外部表。

4.导出数据

如果数据文件恰好是用户需要的格式,那么只需要简单地拷贝文件夹或者文件就可以了:

hadoop fs -cp source_path target_path

否则,用户可以使用INSERT … DIRECTORY …,如下例子所示:

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';

上述URL也可以是全路径 hdfs://master-server/tmp/ca_employees

Hive会将所有字段序列化成字符串写入到文件中,Hive使用和Hive内部存储的表相同的编码方式来生成暑输出文件。

我们可以在hive CLI中查看结果文件的内容:

hive> ! ls /tmp/ca_employees
000000_0
hive> ! cat /tmp/payroll/000000_0
John Doe100000.0201 San Antonio CircleMountain ViewCA94040
Mary Smith80000.01 Infinity LoopCupertinoCA95014
...

文件名为000000_0。如果有两个或者多个reducer来写输出的话,那么我们就可以看到其他相似命名的文件(例如,000000_1)。

和向表中插入数据一样,用户也是可以通过如下方式指定多个输出文件夹目录的:

FROM staged_employees se
INSERT OVERWRITE DIRECTORY '/tmp/or_employees'
	SELECT * WHERE se.cty = 'US' and se.st = 'OR'
INSERT OVERWRITE DIRECTORY '/tmp/or_employees'
	SELECT * WHERE se.cty = 'US' and se.st = 'CA'
INSERT OVERWRITE DIRECTORY '/tmp/or_employees'
	SELECT * WHERE se.cty = 'US' and se.st = 'IL';

为了格式化字段,Hive提供了一些内置函数,其中包括那些由于字符串格式化的操作、例如转换操作,拼接输出操作等。当然,用户可以订制OUTPUTFORMAT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值