既然Hive没有行级别的数据插入、数据更新和删除操作,那么往表中装载数据的唯一途径就是使用一种“大量”的数据装载操作。或者通过其他方式仅仅将文件写入到正确的目录下。

在《​​HiveQL的数据定义(四):分区表和管理表​​​》中我们已经看到了一个如何装载数据到管理表中的例子,这里我们稍微对其增加些内容重新进行展示。我们新增了一个关键字​​OVERWRITE​​:

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

如果分区目录不存在的话,这个命令会先创建分区目录,然后再将数据拷贝到该目录下。如果目标表是非分区表,那么语句中应该省略​​PARTITION​​子句。

通常情况下指定的路径应该是一个目录,而不是单个独立的文件。Hive会将所有文件都拷贝到这个目录中。这使得用户将更方便地组织数据到多文件中,同时,在不修改Hive脚本的前提下修改文件命名规则。不管怎么样,文件都会被拷贝到目标表路径下而且文件名会保持不变。

如果使用了​​LOCAL​​​这个关键字,那么这个路径应该为本地文件系统路径。数据将会被拷贝到目标位置。如果省略掉​​LOCAL​​​关键字,那么这个路径应该是分布式文件系统中的路径。这种情况下,数据是从这个路径转移到目标位置的。​​LOAD DATA LOCAL…​​​拷贝本地数据到位于分布式文件系统上的目标位置,而​​LOAD DATA …​​转移数据到目标位置。之所以会存在这种差异,是因为用户在分布式文件系统中可能并不需要重复的多份数据文件拷贝。

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

指定全路径会具有更好的鲁棒性,但也同样支持相对路径。当使用本地模式执行时,相对路径相对的是当Hive CLI启动时用户的工作目录。对于分布式或者伪分布式模式,这个路径解读为相对于分布式文件系统中用户的根目录,该目录在HDFS和MapRFS中默认为​​/user/$USER​​。

如果用户指定了​​OVERWRITE​​关键字,那么目标文件夹中之前存在的数据将会被先删除掉。如果没有这个关键字,仅仅会把新增的文件增加到目标文件夹中而不会删除之前的数据。如果没有使用OVERWRITE关键字,而目标文件夹下已经存在同名的文件时,会保留之前的文件并且会重命名新文件为“之前的文件名_序列号”。

如果目标表是分区表那么需要使用​​PARTITION​​子句,而且用户还必须为每个分区的键指定一个值。按照前面文章所说的那个例子,数据现在将会存放到如下这个文件夹中:

hdfs://master_server/user/hive/warehouse/mydb.db/employees/country=US/state=CA

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

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