Hive 可以使用load、insert 等操作命令来向表中装载数据,也可以使用insert 子句将数据导出到HDFS。
(1)数据导入
1)使用load 方式导入数据
load 命令可以一次性向表中导入大量的数据,语法格式为:“load data [local]inpath '数据文件目录' [overwrite]into table table_name [partiton(分区值)];”。
关键字local 用于确定导入的文件是位于本地路径还是HDFS 目录。加上local 关键字,表示将本地文件复制并上传到HDFS 指定目录。不加local,Hive 则是将HDFS 上的数据移动到指定目录(而不是复制)。无论是本地的数据还是HDFS 上的数据,都可以使用相对路径和绝对路径这两种方式进行导入。
①导入本地数据
在本地“/home/apache/data/hive/data”目录下新建文件“employeeinfo1.txt”,内容如下:
将“/home/apache/data/hive/data”目录中的文件导入到内部表employee 中:
如果employee 表中已有记录,但想将这些记录覆盖掉,可以加上overwrite 关键字,命令为:
如果是将数据导入到分区表,则需要在命令中指定分区值。例如,将“/home/apache/data/hive/data”目录下的文件导入到分区表“employee_partition”中,指定分区值为beijing。
执行完上述命令语句后,“employeeinfo1.txt”文件中的数据全部导入“employee_partition”表的beijing 分区中。在HDFS 上可以看到,在“employee_partition”目录下有一个“city =beijing”的目录,里面存在文件“employeeinfo1.txt”,如图7.20 所示。
图7.20 导入数据到分区表
②导入HDFS 上的数据
不加local 关键字可以导入HDFS 上的数据。这里先通过复制employee 表来创建新表“employee_copy”,通过复制“employee_partition”来创建新的分区表“employee_partition3”。然后将“employeeinfo1. txt”文件上传到HDFS:“hdfs dfs -put /home/apache/data/hive/data/employeeinfo1.txt /hdfstest”。
将HDFS 中“/hdfstest”目录下的employeeinfo1.txt 导入到employee_copy 表中。
命令执行完后,“employeeinfo1. txt”由“/hdfstest”目录移到“/user/hive/warehouse/apachedb.db/employee_copy”目录下。此时,进行“employee_partition3”数据表导入前,需要将本地的“employeeinfo1.txt”文件再次上传到HDFS 的“/hdfstest”目录,然后才能执行导入命令。
load data inpath '/hdfstest/employeeinfo1. txt' into table employee_partition3 partition(city='beijing');
执行完后,文件由“/hdfstest”目录移动到“/user/hive/warehouse/apachedb. db/employee_partition3/city=beijing”目录中。
2)使用insert 方式导入数据
Hive 可利用insert 关键字向表中插入数据,语法格式为:“insert into table table_name [partition(分区值)]values(值1,值2,…);”。也可以结合select 子句构成查询插入方式,语法为:“insert into table table_name [partition(分区值)]select 子句;”。这种方式实际上是将insert 语句转换成MapReduce 任务来执行。
例如,往employee 表中插入一条数据。
如果是分区表,则必须指定分区。例如,向分区表“employee_partition”中插入一条数据。
结合select 子句进行查询就是将select 查询的结果插入到insert 语句中的表中,select 查询的所有字段都必须在insert 后面的表中定义,且字段的格式需要一致。其示例如下:
使用select 子句可实现一次查询多次插入,这种方式可以减少查询操作扫描数据的次数,从而提高SQL 语句的执行效率。先通过“employee_partition”表复制出三个结构相同的表,如图7.21 所示。
图7.21 创建三个分区表
使用只查询一次的方式向这三个分区表插入数据,如图7.22 所示。
其中,employee_ptn2 表在插入的过程中使用overwite 关键字实现数据覆盖。数据插入成功后,在HDFS 中数据表目录下有一个“city =beijing”的目录,里面有一个名称为“000000_0”文件,这个就是数据表文件。可以使用dfs 命令查看文件内容,如图7.23 所示。
图7.22 使用insert 实现一次查询多次插入(www.xing528.com)
图7.23 使用dfs 命令查看数据表文件内容
3)动态分区插入数据
前面对分区表插入数据用的都是静态分区插入的方式,也就是手动指定分区。Hive 也支持动态分区插入数据,即通过查询出来的分区字段的值来进行自动判断,从而创建出需要的分区,每一个不同分区值就会创建一个对应的分区。
在默认情况下,Hive 并没有开启动态分区功能,需要手动开启。在Hive 命令行下输入以下两条命令:第一条是打开动态分区的开关,第二条是设置动态分区插入模式。
设置好参数后,就可以利用动态分区往表中插入数据。创建表“employee_ptn4”,通过department字段分区。
利用动态分区向表中插入数据:
命令执行成功后,通过show partitions 命令查看分区情况以及每个分区中的数据,结果如图7.24所示。
需要注意的是,动态分区插入的分区字段必须位于select 查询语句中出现的字段的末尾。上述命令中,select 子句中的字段id、name、sex 和age 都是分区表“employee_ptn4”的普通字段,而最后一个department 则是“employee_ptn4”的分区字段。
4)通过查询建表来加载数据
Hive 支持直接将查询出来的结果存储到新建的一张表里,新表的字段与查询语句出现的字段结构一样。例如,使用查询建表来创建一个表名为“employee_ctas”的表,并将employee 表中的数据查询出来插入到“employee_ctas”中。
图7.24 利用动态分区插入数据结果
employee_ctas 表结构及表中的数据如图7.25 所示。
(2)清空数据表中的数据
使用truncate 关键字可以清空数据表,语法为:“truncate table table_name;”。清空内部表、外部表和分桶表时,会将数据存储目录下的所有数据文件都删掉。而清空分区表时,只会清空分区下的数据文件,不会删掉分区。要将分区也删除,可使用dfs 命令完成。
(3)数据导出
使用insert 命令可以将数据仓库中的数据导出到本地或者HDFS 中,语法格式为:“insert overwrite [local]directory 导出目录 数据分隔格式 select 子句;”。
1)导出数据到本地
将employee 表中的字段为id、name、sex 和department 的数据导出到本地“/home/apache/data/hive/data”目录下。
命令执行完成后,本地“/home/apache/data/hive/data”目录下多了一个名为“000000_0”的文件,这个就是导出的文件,可以使用cat 命令查看其内容,如图7.26 所示。
图7.25 employee_ctas 表结构及表中的数据
图7.26 导出数据到本地
Hive 也支持多模式导出,例如,将employee 中的数据导出到本地“/home/apache/data/hive/data 和/home/apache/data/hive/data2”目录中。
2)导出数据到HDFS
在HDFS 上新建目录“/user/hive/data/employee”,在终端中执行命令:“hdfs dfs -mkdir -p/user/hive/data/employee”。选择employee 表中的数据导出到HDFS 的“/user/hive/data/employee”目录。
使用dfs 命令查看导出结果,如图7.27 所示。
图7.27 数据导出到HDFS 的结果
数据导出到HDFS 也可以使用多模式导出的方式,实现一次查询多次导出。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。