一、向管理表中装载数据

Hive没有行级别的数据插入、更新和删除操作,往表中装载数据的唯一途径就是使用一种“大量”的数据装载操作。

LOAD:向表中装载数据

(1)把目录‘/usr/local/data’下的数据文件中的数据装载进usr表,并覆盖原有数据:LOAD DATA LOCAL INPATH ‘/usr/local/data’ OVERWRITE INTO TABLE usr;

(2)把目录‘/usr/local/data’下的数据文件中的数据装载进usr表, 不覆盖原有数据:LOAD DATA LOCAL INPATH ‘/usr/local/data’  INTO TABLE usr;

(3)把分布式文件系统目录'hdfs://master_server/usr/local/data’下的数据文件数据装载进usr表,并覆盖原有数据:LOAD DATA INPATH ‘hdfs://master_server/usr/local/data’ OVERWRITE INTO TABLE usr;

举例:

LOAD DATA LOCAL INPATH '${env:HOME}/california-employees' # ${env:HOME}表示HOME环境变量
INTO TABLE employees
PARTITION (country='US',state='CA');

如果分区目录不存在,会先创建分区目录,然后将数据拷贝到该目录下。

如果目标是非分区表,语句中应该省略PARTITION子句。

二、通过查询语句向表中插入数据

INSERT:通过查询语句向表中插入数据

(1)向表usr1中插入来自usr表的数据并覆盖原有数据:INSERT OVERWRITE TABLE usr1 SELECT * FROM usr WHERE age=10;

(2)向表usr1中插入来自usr表的数据并追加在原有数据后:INSERT INTO TABLE usr1 SELECT * FROM usr WHERE age=10;

举例:

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次。可以只扫描一次staged_employees表,然后按多种方式进行划分(可以混合使用INSERT OVERWRITE和INSERT INTO):

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='CA')
    SELECT * WHERE se.cnty = 'US' AND se.st = 'CA'
...;

三、动态分区插入

基于查询参数推断出需要创建的分区名称,用于创建非常多的分区。

INSERT OVERWRITE TABLE employee
PARTITION (country,state)
SELECT ...,se.cnty,se.st #根据select语句中最后2列确定分区字段country和state的值
FROM staged_employees se;

也可以混合使用动态和静态分区,静态分区必须出现在动态分区键之前:

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

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

Hive编程指南-学习笔记(三) 数据操作-LMLPHP

四、单个查询语句中创建表并加载数据

不能用于外部表。

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

五、导出数据

如果数据文件恰好是需要的格式,只需要拷贝文件夹或文件:

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';

可以指定多个输出文件夹目录:

FROM staged_employees se
INSERT OVERWRITE DIRECTORY '/tmp/or_employees'
    SELECT * WHERE se.cnty = 'US' AND se.st = 'OR'
INSERT OVERWRITE DIRECTORY '/tmp/ca_employees'
    SELECT * WHERE se.cnty = 'US' AND se.st = 'CA'
...;
10-05 17:47