一、向管理表中装载数据
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';
动态分区功能默认是关闭的。开启后,默认是以“严格”模式执行,这种模式下要求至少有一列分区字段是静态的,有助于防止因设计错误导致产生大量的分区。
四、单个查询语句中创建表并加载数据
不能用于外部表。
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'
...;