1,数据导入与导出
数据导入
对于hive而言,对数据更多是查询导入与导出,那么hive数据如何导入呢?
两种方式导入数据
首先创建一张学生表
create table student(
id INT,
name STRING,
age INT
)
row format delimited fields terminated by ','
第一种导入数据方式,直接再hdfs上导入文本到hive相关表的默认目录下例如/user/hive/warehouse/test.db/student
hadoop dfs -cp /test.txt /user/hive/warehouse/test.db/student
现在查看学生表
第二种方式 load 命令hive官方推荐
load data inpath '/test.txt' into table student;
这是我喜欢用的,完整的语句为
load data [local] inpath '数据的 path' [overwrite] into table
student [partition (partcol1=val1,…)];
(1)load data:表示加载数据
(2)local:表示从本地加载数据到 hive 表;否则从 HDFS 加载数据到 hive 表
(3)inpath:表示加载数据的路径
(4)overwrite:表示覆盖表中已有数据,否则表示追加
(5)into table:表示加载到哪张表
(6)student:表示具体的表
当使用load加载完数据后,我们发现存储源数据路径下,源数据不在啦。实际上hive也是将我们的源数据从加载的位置类似于剪切一样剪切到hive管理的目录下,也就是说laod 的原理实际上是也是mv(linux命令,剪切和重命名)。
当然啦也可以直接再hive相关目录下直接创建文件,写入数据。
数据导出
将数据导出到hdfs上的/student目录下
insert overwrite directory '/student' select * from student
格式化导出
insert overwrite directory '/student'
row format delimited fields terminated by ','
select * from student
将数据导入到本地
insert overwrite local directory '/student' select * from student;
也可以使用
hive命令 -e 重定向方式
hive数据导出除啦我上面介绍的方式,还有export,import,这两个一般用于两个Hadoop集群之间。这里不做介绍,感兴趣的同学可以自己查找相关资料。
2,Hive 分区表
分区表实际上就是hdfs上一个独立的文件夹,该文件下是该分区的所有的数据文件。hive分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时使用where指定分区,这里分区表使用where和其他表中使用的where有本质上区别。分区表中使用where,就只会扫描该文件夹下的文件数据,不会进行全表扫描,而其他表(包括MySQL中的表)使用where都会进行全表扫描。这也是为什么hive会有分区表概念,因为hive一般存储的是大数据集,为了提高查询效率,而使用的一种手段。
创建分区表
create table studentpar1(
id INT,
name STRING,
age INT
)
partitioned by (sex STRING)
row format delimited fields terminated by ','
加载数据
load data local inpath '/root/student.txt' into table studentpar1 partition(sex='nan');
查询
select * from studentpar1 where sex=‘nan’;
删除分区
alter table studentpar1 drop partition(sex=‘nv’);
动态分区,一般来说,hive创建的分区表默认都是静态分区,也就是再数据导入的时候,我们需要手动的指定分区字段如上sex,那么如果我们需要根据查询的字段去动态指定分区字段呢?
hive提供的动态分区表。只不过动态分区表是再静态分区表的基础上增加一些配置。
动态分区参数设置
1开启动态分区功能
hive.exec.dynamic.partition=true
2,设置为非严格模式(默认为strict,表示必须指定只少一个分区为静态分区,nonstrict模式表示允许所有字段为动态分区)
hive.exec.dynamic.partition.mode=nonstrict
3,在所有执行MR的节点上,最大一共可以创建多少个动态分区。默认1000
hive.exec.max.dynamic.partitions=1000
4,在每个执行MR的节点上,最大可以创建多少个分区。例如源数据中包含了一年的数据,即 day 字段有 365 个值,那么该参数就 需要设置成大于 365,如果使用默认值 100,则会报错。
hive.exec.max.dynamic.partitions.pernode=100
5,整个MRJob中,最大可以创建多少个HDFS文件,默认100000
hive.exec.max.created.files=100000
6,当有空分区产生时,是否抛出异常。一般不需要设置,默认false
hive.error.on.empty.partition=false
案例实操
将学生表(student1)按照性别动态分区到studentpar2
创建学生表
create table student1(
id INT,
name STRING,
age INT,
sex STRING
)
row format delimited fields terminated by ','
加载数据
load data local inpath '/root/student.txt' into table student1;
本地/root/student.txt数据
1,a,12,1
2,b,11,1
3,c,45,1
4,d,56,1
5,d,23,1
6,f,22,1
7,g,13,1
#1代表男生
#2代表女生
创建分区表
create table studentpar2(
id INT,
name STRING,
age INT
)
partitioned by (sex STRING)
row format delimited fields terminated by ','
开启相关配置
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.error.on.empty.partition=false;
set hive.exec.max.created.files=100000;
set hive.exec.max.dynamic.partitions.pernode=10000;
set hive.exec.max.dynamic.partitions=50000;
执行查询
insert into table studentpar2 partition(sex) select
* from student1;