Hive分区&分桶
一、实验目的
1.了解Hive的分区。
2.了解Hive的分桶。
二、实验原理
Hive分区是为了方便数据管理,Hive实际存储在HDFS上的抽象,Hive的一个分区名对应一个目录名,子分区名就是子目录名,并不是实际的一个字段,所以当我们在插入数据的时候后指定分区,其实就是新建一个目录或者子目录,或者在原有的目录上添加数据文件。
Hive创建分区时是通过PARTITIONED BY关键字进行创建,要注意这个关键字定义的列是表中正式的列,不能与表中其他列名重复,但是Hive下数据文件不包含这些列,他们是目录(分区)名,目录下放的才是数据。通过表分区能够在特定的区域检索数据,减少扫描成本,在一定程度上可以提高效率。
Hive分桶是指分通表的某一列,让该列数据按照哈希取余的方式随机,均匀的分发到各个桶文件中。在分桶中需要根据指定列的具体数据进行哈希取余操作,所以分同列必须基于表中的某一列(字段)。分桶改变了数据的存储方式,他会把哈希值取余相同或者在某一区间的数据行放在同一个桶文件中。便于提高插叙效率。
三、实验环境
Linux Ubuntu 16.04
jdk-7u75-linux-x64
hive-1.1.0-cdh5.4.5
hadoop-2.6.0-cdh5.4.5
mysql-5.7.24
四、实验内容
1、前期工作
1.打开终端模拟器,启动Hadoop进程,切换到/apps/hadoop/sbin目录下,输入命令./start-all.sh启动命令。
cd /apps/hadoop/sbin
./start-all.sh
2.开启Mysql服务。
sudo service mysql start
3.Mysql启动之后,启动Hive数据仓库。
hive
4.在Hive中创建名为zhangyu的库。
create database zhangyu;
切换到zhangyu的库。
use zhangyu;
5.在Hive中创建一个zy表,用来存储最原始的数据,由这个表中向其他表中导入数据。
create table zy(
id int,
name string,
age int,
language array<string>,
city map<string,string>
)row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
表后面是表中数据的规则,row表示行的设置,fields是设置字段的分隔符,collection表示设置集合的分隔符,map表示设置集合的分隔符。
6.新开启一个终端,在data目录下新建一个data.txt文件。
cd /data
vim data.txt
data.txt中的内容如下:
新建一个clu.txt文件。
vim clu.txt
clu.txt中的内容如下:
7.在Hive中把数据导入到刚刚新建的zy表中。
load data local inpath '/data/data.txt' into table zy;
数据插入之后可以查询下数据。
select * from zy;
2、分区
8.新建分区表,这里边是静态分区,创建一个静态分区表。
create table zy1(
id int,
name string,
language array<string>,
city map<string,string>
)partitioned by(age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
partitioned表示设置分区,括号中的内容是分区列。注意分区列不需要在列中设置,而是在设置分区时直接指定,如果在列中设置整个语句将要报错。
9.向分区表中插入数据,把zy中的数据插入到zy1表中数据。
from zy
insert into table zy1 partition (age=12)
select id,name,language,city;
注意:上面的语句表示把zy的表数据插入到zy1中。partition表示分区后面的括号中是分区列,由于这次是静态分区,所以直接指定分区的值。执行上面语句的时候需要执行MapReduce。
10.再次插入分区数据。
from zy
insert into table zy1 partition (age=13)
select id,name,language,city;
查询表,表中尾部数据,就是看到的分区内容。
select * from zy1;
上面展示的是静态分区,根据指定的分区值进行分区。
动态分区,根据列值的不同进行分区,不需要指定值,直接获取列的值。
11.创建一个名为zy2的动态分区表。
create table zy2(
id int,
name string,
language array<string>,
city map<string,string>
)partitioned by(age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
12.在导入数据之前,首先要设置允许动态分区。下面的属性表示允许动态分区。
set hive.exec.dynamic.partition.mode=nonstrict;
从zy中导入数据到zy2表中,在执行中也需要调用MapReduce。
from zy
insert into table zy2 partition (age)
select id,name,language,city,age;
13.查询zy2表中数据。
select * from zy2;
3、分桶
14.创建一个表,用来存放原始数据,其他分桶的数据都是从这个表中拿取数据。
create table clu(
id int,
name string,
age int
)row format delimited
fields terminated by ',';
15.导入数据,把clu.txt文件内容导入到表中。
load data local inpath '/data/clu.txt' into table clu;
16.设置允许分桶。
SET hive.enforce.bucketing=true;
创建一个分桶表。
create table clu1(
id int,
name string,
age int
)clustered by (age) into 4 buckets
row format delimited
fields terminated by ',';
clustered表示设置分桶,括号中参数表示分桶的参数,后的数字4表示在本次分桶中分了四个桶。
17.从clu中导入数据到clu1中。
from clu
insert into table clu1
select id,name,age;
查看表中数据,可以看到数据已经按照分桶分了数据。
select * from clu1;
总结
Hive分区是为了方便数据管理,Hive实际存储在HDFS上的抽象,Hive的一个分区名对应一个目录名,子分区名就是子目录名,并不是实际的一个字段,所以当我们在插入数据的时候后指定分区,其实就是新建一个目录或者子目录,或者在原有的目录上添加数据文件。
Hive创建分区时是通过PARTITIONED BY关键字进行创建。
Hive分桶是指分通表的某一列,让该列数据按照哈希取余的方式随机,均匀的分发到各个桶文件中。