【大数据Hive】hive 加载数据常用方案使用详解

目录

一、前言

二、load 命令使用

2.1 load 概述

2.1.1 load 语法规则

2.1.2 load语法规则重要参数说明

2.2 load 数据加载操作演示

2.2.1 前置准备

2.2.2 加载本地数据

2.2.3 HDFS加载数据

2.2.4 从HDFS加载数据到分区表中并指定分区

2.3 hive3.0+ load 命令新特性

2.3.1 操作演示

三、insert 命令使用

3.1 语法

3.2 insert + select 操作演示

3.2.1 创建一张源表

3.2.2 加载数据

3.2.3 创建一张目标表

3.2.4 使用insert+select插入数据到新表

3.3 multiple inserts

3.3.1 操作演示

3.4 insert 之动态分区插入

3.4.1 动态分区概述

3.4.2 操作演示

3.5 insert 之导出数据

3.5.1 标准语法

3.5.2 其他写法

3.5.3 导出数据操作演示1

3.5.4 导出数据操作演示2

3.5.5 导出数据操作演示3

四、写在文末


一、前言

使用hive对数据表加载数据时方式有很多,比如直接通过insert into插入数据,或者先创建表,然后在hdfs上面上传数据文件进行数据加载的方式等等,本篇将重点介绍如何对hive的table进行数据的导入导出。

二、load 命令使用

在正式开始之前,先来回顾下之前的文章中讲到的一种常用的数据加载方式,即使用load的方式进行数据映射;

总结来说,包括如下几点:

  • 在Hive中建表成功之后,就会在HDFS上创建一个与之对应的文件夹,且文件夹名字就是表名;
  • 文件夹父路径是由参数hive.metastore.warehouse.dir控制,默认值是/user/hive/warehouse;
  • 也可以在建表的时候使用location语句指定任意路径;

【大数据Hive】hive 加载数据常用方案使用详解_第1张图片

默认情况下,当我们创建完成一个table之后,不管路径在哪里,只有把数据文件移动到对应的表文件夹下面,Hive才能映射解析成功,最原始的方式就是使用 hadoop fs –put|-mv 等方式直接将数据移动到表文件夹下,但是,Hive官方推荐使用Load命令将数据加载到表中;

2.1 load 概述

Load英文单词的含义为:加载、装载,所谓加载是指:将数据文件移动到与Hive表对应的位置,移动时是纯复制、移动操作;

纯复制、移动指在数据load加载到表中时,Hive不会对表中的数据内容进行任何转换,任何操作;

2.1.1 load 语法规则

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

或者

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)

2.1.2 load语法规则重要参数说明

语法规则之filepath

  • filepath表示待移动数据的路径。可以指向文件(在这种情况下,Hive将文件移动到表中),也可以指向目录(在这种情况下,Hive将把该目录中的所有文件移动到表中);
  • filepath文件路径支持下面三种形式,要结合LOCAL关键字一起考虑;

filepath可以使用绝对路径或者相对路径

1、相对路径,例如:project/data1;

2、绝对路径,例如:/user/hive/project/data1;

3、具有schema的完整URI,例如:hdfs://namenode:9000/user/hive/project/data1;

语法规则之 local

  • 指定LOCAL, 将在本地文件系统中查找文件路径;

1、若指定相对路径,将相对于用户的当前工作目录进行解释;

2、用户也可以为本地文件指定完整的URI-例如:file:///user/hive/project/data1

如果没有指定 local 关键字

  • 如果filepath指向的是一个完整的URI,会直接使用这个URI;
  • 如果没有指定schema,Hive会使用在hadoop配置文件中参数fs.default.name指定的(不出意外,都是HDFS);

问题:LOCAL本地是哪里?

如果对HiveServer2服务运行此命令,本地文件系统指的是Hiveserver2服务所在机器的本地Linux文件系统,不是Hive客户端所在的本地文件系统

语法规则之 OVERWRITE

如果使用了OVERWRITE关键字,则目标表(或者分区)中的已经存在的数据会被删除,然后再将filepath指向的文件/目录中的内容添加到表/分区中。

2.2 load 数据加载操作演示

模拟从本地加载数据

2.2.1 前置准备

创建三张表,分别演示从本地以及hdfs上面加载数据

create table student_local(
    num int,
    name string,
    sex string,
    age int,
    dept string) 
row format delimited fields terminated by ',';

【大数据Hive】hive 加载数据常用方案使用详解_第2张图片

再创建第二张表

create external table student_HDFS(
    num int,
    name string,
    sex string,
    age int,
    dept string) 
row format delimited fields terminated by ',';

【大数据Hive】hive 加载数据常用方案使用详解_第3张图片

创建第三张分区表,用于演示从HDFS加载数据到分区表

create table student_HDFS_p(
    num int,
    name string,sex string,
    age int,
    dept string) 
partitioned by(country string) row format delimited fields terminated by ',';

【大数据Hive】hive 加载数据常用方案使用详解_第4张图片

2.2.2 加载本地数据

从本地加载数据 

LOAD DATA LOCAL INPATH '/usr/local/soft/hivedata/students.txt' INTO TABLE student_local;

执行完成后查看表,可以看到数据就加载到表中了; 

【大数据Hive】hive 加载数据常用方案使用详解_第5张图片

 同时再去检查hdfs目录,可以看到数据也被加载到hdfs目录下了;

【大数据Hive】hive 加载数据常用方案使用详解_第6张图片

  其实,这种操作其底层在执行时,本质上还是执行了是hadoop fs -put上传的操作

2.2.3 HDFS加载数据

将数据上传到hdfs

hdfs dfs -put /usr/local/soft/hivedata/students.txt /

 上传成功后,在根目录下就可以看到这个文件了

【大数据Hive】hive 加载数据常用方案使用详解_第7张图片

将上述hdfs根目录下的数据移动到表中

LOAD DATA INPATH '/students.txt' INTO TABLE student_HDFS;

【大数据Hive】hive 加载数据常用方案使用详解_第8张图片

这时再去hdfs的根目录下检查,发现这个数据文件竟然不在了

【大数据Hive】hive 加载数据常用方案使用详解_第9张图片

 这种加载数据的方式,其本质是hadoop fs -mv 进行数据移动的操作

2.2.4 从HDFS加载数据到分区表中并指定分区

上传数据到根目录

hdfs dfs -put /usr/local/soft/hivedata/students.txt /

【大数据Hive】hive 加载数据常用方案使用详解_第10张图片

使用load命令将数据加载到分区表

LOAD DATA INPATH '/students.txt' INTO TABLE student_HDFS_p partition(country ="China");

【大数据Hive】hive 加载数据常用方案使用详解_第11张图片

2.3 hive3.0+ load 命令新特性

Hive3.0之后,load加载数据时除了移动、复制操作之外,在某些场合下还会将加载重写为INSERT AS SELECT,还支持使用inputformat、SerDe指定输入格式,例如Text,ORC等。

比如,如果表具有分区,则load命令没有指定分区,则将load转换为INSERT AS SELECT,并假定最后一组列为分区列,如果文件不符合预期,则报错。

2.3.1 操作演示

创建一张测试使用的分区表

CREATE TABLE if not exists tab1 (col1 int, col2 int)
PARTITIONED BY (col3 int)
row format delimited fields terminated by ',';

创建一个数据文件,格式如下


正常情况下的数据加载

LOAD DATA LOCAL INPATH '/usr/local/soft/hivedata/tab1.txt' INTO TABLE tab1 partition(col3="1");

加载完成后可以看到数据已经加载到表中

【大数据Hive】hive 加载数据常用方案使用详解_第12张图片

上面谈到hive3.0之后,load命令如果没有指定分区,则将load转换为INSERT AS SELECT,并假定最后一组列为分区列,接下来我们清空该表,使用下面的命令重新执行一次;

LOAD DATA LOCAL INPATH '/usr/local/soft/hivedata/tab1.txt' INTO TABLE tab1;

【大数据Hive】hive 加载数据常用方案使用详解_第13张图片

 从hdfs上面可以发现,被成功映射为分区表了;【大数据Hive】hive 加载数据常用方案使用详解_第14张图片

通过执行过程发现,这个时间有点长,因为底层要将这个操作转化为 INSERT AS SELECT 的操作;

三、insert 命令使用

MySQL这样的RDBMS中,通常使用insert+values的方式来向表插入数据,并且执行速度很快,假如把Hive当成RDBMS,用insert+values的方式插入数据,会如何?

不妨来做过简单的试验吧,创建一张表

create table t_test_insert(id int,name string,age int);

然后向表中插入一条数据

insert into table t_test_insert values(1,"allen",18);

尽管数据可以插入成功,但是执行过程比较漫长,原因在于底层是开启了了MapReduce任务,通过map-reduce任务把数据写入Hive表中;

【大数据Hive】hive 加载数据常用方案使用详解_第15张图片

试想一下,如果在Hive中使用insert+values,对于大数据环境一条条插入数据,用时难以想象,所以Hive官方推荐加载数据的方式:清洗数据成为结构化文件,再使用Load语法加载数据到表中。这样的效率更高。

但是并不意味insert语法在Hive中没有用武之地了,下面介绍hive中insert的其他用法;

insert + select

insert+select表示:将后面查询返回的结果作为内容插入到指定表中,注意OVERWRITE将覆盖已有数据;

3.1 语法

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+select 需要注意:

  • 需要保证查询结果列的数目和需要插入数据表格的列数目一致;
  • 如果查询出来的数据类型和插入表格对应的列数据类型不一致,将会进行转换,但是不能保证转换一定成功,转换失败的数据将会为NULL;

3.2 insert + select 操作演示

3.2.1 创建一张源表

create table student(num int,name string,sex string,age int,dept string)
row format delimited
fields terminated by ',';

【大数据Hive】hive 加载数据常用方案使用详解_第16张图片

3.2.2 加载数据

load data local inpath '/usr/local/soft/hivedata/students.txt' into table student;

【大数据Hive】hive 加载数据常用方案使用详解_第17张图片

3.2.3 创建一张目标表

该表只有两个字段

create table student_from_insert(sno int,sname string);

3.2.4 使用insert+select插入数据到新表

不难理解,执行了这条sql之后,student表中的num,name两个字段数据将会填充到student_from_insert表中;

insert into table student_from_insert select num,name from student;

【大数据Hive】hive 加载数据常用方案使用详解_第18张图片

3.3 multiple inserts

顾名思义就是,多次插入,多重插入,其核心功能是:一次扫描,多次插入;

使用该语法的目的就是减少扫描的次数,在一次扫描中,完成多次insert操作;

3.3.1 操作演示

在上面的insert + select 中创建了一张student的表,再创建两张新表,各有一个字段;

create table student_insert1(sno int);
create table student_insert2(sname string);

【大数据Hive】hive 加载数据常用方案使用详解_第19张图片

我们的需求是,从student中查询出sno放到第一个表,然后查询出sname放到另一个表中,如果按照大多数人直观的考虑,可能会像下面这么做:

insert into student_insert1 select num  from student;

insert into student_insert2 select name  from student;

如果使用多重插入来做的话,就可以使用下面的sql一次性完成;

from student
insert overwrite table student_insert1
select num
insert overwrite table student_insert2
select name;

【大数据Hive】hive 加载数据常用方案使用详解_第20张图片

执行完成后,可以检查两个表的数据是否成功插入;

【大数据Hive】hive 加载数据常用方案使用详解_第21张图片

3.4 insert 之动态分区插入

背景说明

对于分区表的数据导入加载,最基础的是通过load命令加载数据,在load过程中,分区值是手动指定写死的,叫做静态分区。

假如说,现在有全球224个国家的人员名单(每个国家名单单独一个文件),导入到分区表中,不同国家不同分区,如何高效实现?如果使用load命令,岂不是要导入224次?这样的话效率就太低了。

3.4.1 动态分区概述

动态分区插入指的是:分区的值是由后续的select查询语句的结果来动态确定的,根据查询结果自动分区。

两个重要参数

hive.exec.dynamic.partition true 需要设置true为启用动态分区插入
hive.exec.dynamic.partition.mode strict 在strict模式下,用户必须至少指定一个静态分区,以防用户意外覆盖所有分区;在nonstrict模式下,允许所有分区都是动态的

3.4.2 操作演示

首先设置动态分区模式为非严格模式(默认已经开启了动态分区功能)

set hive.exec.dynamic.partition = true;

set hive.exec.dynamic.partition.mode = nonstrict;

在当前库下,已经有一张student表,创建分区表;

create table student_partition(
    Sno int,
    Sname string,
    Sex string,
    Sage int) 
partitioned by(Sdept string);

【大数据Hive】hive 加载数据常用方案使用详解_第22张图片

执行动态分区insert操作插入数据

insert into table student_partition partition(Sdept)
select num,name,sex,age,dept from student;

 【大数据Hive】hive 加载数据常用方案使用详解_第23张图片

执行完成后,检查hdfs目录,可以发现数据已经按照分区保持了

【大数据Hive】hive 加载数据常用方案使用详解_第24张图片

3.5 insert 之导出数据

Hive支持将select查询的结果导出成文件存放在文件系统中,语法格式如下;

3.5.1 标准语法

INSERT OVERWRITE [LOCAL] DIRECTORY directory1    

[ROW FORMAT row_format] [STORED AS file_format]

SELECT ... FROM ...

3.5.2 其他写法

FROM from_statement

INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1

[INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...

关于语法补充说明

  • 目录可以是完整的URI。如果未指定scheme,则Hive将使用hadoop配置变量fs.default.name来决定导出位置;
  • 如果使用LOCAL关键字,则Hive会将数据写入本地文件系统上的目录;
  • 写入文件系统的数据被序列化为文本,列之间用\001隔开,行之间用换行符隔开。如果列都不是原始数据类型,那么这些列将序列化为JSON格式。也可以在导出的时候指定分隔符换行符和文件格式;

3.5.3 导出数据操作演示1

在上文中演示时用到了一张student表

导出查询结果到HDFS指定目录下

insert overwrite directory '/data' select num,name,age from student;

【大数据Hive】hive 加载数据常用方案使用详解_第25张图片

任务完成之后到hdfs目录下检查数据是否导出成功,也可以从hdfs将文件下载下来再次确认数据的正确性;

 【大数据Hive】hive 加载数据常用方案使用详解_第26张图片

3.5.4 导出数据操作演示2

接下来我们在导出的时候指定一下分隔符和文件存储格式

insert overwrite directory '/data' row format delimited fields terminated by ','
stored as orc select * from student;

执行上面的导出sql

【大数据Hive】hive 加载数据常用方案使用详解_第27张图片

 去hdfs上检查数据是否导出成功

【大数据Hive】hive 加载数据常用方案使用详解_第28张图片

3.5.5 导出数据操作演示3

导出数据到本地文件系统指定目录下

insert overwrite local directory '/usr/local/soft/data' select * from student;

【大数据Hive】hive 加载数据常用方案使用详解_第29张图片

 执行完成之后检查本地数据目录下已经有了导出的数据;

【大数据Hive】hive 加载数据常用方案使用详解_第30张图片

四、写在文末

hive的数据导入在日常开发、运维过程中运用的场景非常普遍,且频率非常高,选择合理的数据导入方式可以给开发提升很多效率,有必要深入掌握。

你可能感兴趣的:(大数据,hive加载数据,hive加载外部数据,hive数据加载,hive,load数据,hive,load)