使用Load语句可以方便的将本地文件系统或者HDFS中的文件加载到Hive表中,语句格式如下:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename[PARTITION (partcol1=val1, partcol2=val2 ...)]
在该语句中,如果包含LOCAL关键字,则复制本地文件系统中的文件到目标表中,如果不包含LOCAL关键字,则移动文件到目标表中。示例如下:
hive> dfs -lsr /user/hadoop/iis/input;
-rw-r--r-- 1 hadoop supergroup 3287 2014-07-01 09:59/user/hadoop/iis/input/iis.log
hive> loaddata inpath '/user/hadoop/iis/input/iis.log' into table idppartition(createDate='2014-03-03', source=1);
Loading data totable logdb.idp partition (createdate=2014-03-03, source=1)
Partitionlogdb.idp{createdate=2014-03-03, source=1} stats: [numFiles=1, numRows=0,totalSize=3287, rawDataSize=0]
OK
Time taken:1.499 seconds
hive> dfs -lsr /user/hadoop/iis/input;
hive> dfs -lsr /user/hive/warehouse/logdb.db/idp;
drwxr-xr-x - hadoop supergroup 0 2014-07-01 10:21/user/hive/warehouse/logdb.db/idp/createdate=2014-03-03
drwxr-xr-x - hadoop supergroup 0 2014-07-01 10:22/user/hive/warehouse/logdb.db/idp/createdate=2014-03-03/source=1
-rw-r--r-- 1 hadoop supergroup 3287 2014-07-01 10:22/user/hive/warehouse/logdb.db/idp/createdate=2014-03-03/source=1/iis.log
如果表是分区表则必须指定PARTITION从句,否则会报如下错误:
FAILED:SemanticException [Error 10062]: Need to specify partition columns because thedestination table is partitioned
从上面的演示可以看出,Load语句在加载数据到表中时不会对数据做任何转换,该操作只是单纯地复制或者移动数据文件到Hive表对应的位置。Load语句中的filepath既可以是单个文件也可以是目录,如果是目录的话不可以包含子目录。前一种情况复制或者移动文件到表中,后一种情况复制或者移动目录中的所有文件到表中。Filepath既可以是相对路径,如iis.log,也可以是绝对路径,如/usre/hadoop/iis/input/iis.log,还可以是带有scheme和authority的完整URI,如hdfs://Hadoop:9000/ usre/hadoop/iis/input/iis.log。
如果使用了LOCAL关键字,则会在本地文件系统中寻找filepath,如果filepath是相对路径,则该路径会被解释为相对于用户的当前工作目录,用户也可以指定为本地文件指定完整URI,例如:file:///home/hadoop/iis.log,或者直接写为/home/hadoop/iis.log。Load语句将会复制由filepath指定的所有文件到目标文件系统(目标文件系统由表的location属性推断得出),然后移动文件到表中。
如果未使用LOCAL关键字,filepath必须指的是与目标表的location文件系统相同的文件系统上的文件。Hive或者使用filepath的完整URI,或者使用下面所示的规则:
如果使用了OVERWRITE关键字,目标表或者分区中的内容将被删除并被替换为filepath指定的文件,若未使用OVERWRITE关键字,文件将会被增加到表中。如果目标表或者分区的某个文件与filepath包含的文件名冲突,则新文件将替换已经存在的文件。
Hive执行最小化的检查以确保正在加载的文件与目标表匹配,目前Hive仅检查表的存储格式与被加载的文件格式是否相同,即如果加载textfile到sequencefile就会出现错误。
Insert语句的标准语法格式为:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
INSERT OVERWRITE语句将会覆盖表或者分区中任何存在的数据,但如果为分区指定了IF NOT EXISTS关键字则不会覆盖分区中的数据。Hive还支持多个插入操作,语法如下:
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]]select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2]
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;
FROM from_statement
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2]
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2] ...;
多表插入最小化了要求的数据扫描次数,Hive可以仅扫描输入数据一次并应用不同的查询操作符,然后将数据插入多个表中。
INSERT INTO语句添加数据到表或者分区中,且保持现存数据完好无缺。Insert语句可以应用于表或分区,如果是一个分区表,在插入数据时必须通过指定所有分区列的值来指定表的分区。
Hive还支持动态分区插入,用户可以在PARTITION从句中仅指定分区列的名称,分区列的值是可选的。如果给定分区列的值,称该分区列为静态分区,否则为动态分区。每个动态分区列对应select子句的一个输入列,动态分区列必须在select子句中所有输入列的最后指定,并且与它们在PARTITION从句出现的顺序保持一致。动态分区插入的语法为:
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...)select_statement FROM from_statement;
INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;
默认情况下动态分区插入是禁用的,下表是关于动态分区插入的相关配置属性:
配置参数 |
默认值 |
描述 |
hive.error.on.empty.partition |
false |
在动态分区插入产生空结果时是否抛出异常。 |
hive.exec.dynamic.partition |
false |
是否允许动态分区插入,若允许则设置为true。 |
hive.exec.dynamic.partition.mode |
strict |
在strict模式 中用户至少指定一个静态分区以防用户不慎覆盖所有分区,在nonstrict模式中所有分区都允许是动态的。 |
将上面的插入语句稍微改动一下,就可以将查询结果插入到文件系统的目录中,语句如下:
INSERT OVERWRITE [LOCAL] DIRECTORY directory
[ROW FORMATrow_format] [STORED AS file_format]
SELECT ... FROM...
FROM from_statement
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...
如果指定LOCAL关键字,Hive将向本地文件系统的目录写入数据,写入文件系统的数据会被序列化为文本格式,如果输出列不是基本类型,这些列将被序列化为JSON格式。如果指定的目录存在则会覆盖该目录中的文件。示例如下:
insert overwrite local directory '/home/hadoop/test' row format delimited fields terminated by'\t' select * from idp;