Hive 分区表,
制造数据:
for i in $(seq 50)
do
echo -e "$(date -d "$RANDOM minute ago" +%F' '%T'.'%N)"
done|sort -nk1|awk '{print NR"\t"$0}'>/tmp/order_created.txt
CREATE TABLE order_created_partition(
order_number string,
event_time string
)
PARTITIONED BY (event_month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY “\t”;
– 建表语句,指定分区字段为event_month,这个字段是伪列
– 会在数据load到表的这个分区时,在hdfs上创建名为event_month=2018-10的子目录
load data local inpath ‘/home/hadoop/app/data/order_created.txt’ into table order_created_partition PARTITION (event_month=‘2018-10’);
– 使用 hdfs dfs -cat …/order_created_partition/event_month=2017-12/order_created.txt
– 查看数据文件中并没有event_month这一列
select * from order_created_partition where event_month=‘2018-10’;
– 使用where子句,过滤分区字段,遍历某个分区
– 而使用hdfs dfs -cat看不到该列,说明分区表的分区列是伪列
– 实际上是hdfs中的分区目录的体现
添加分区,load数据:
alter table order_created_partition add partition (event_month=‘2018-11’);
load data local inpath ‘/home/hadoop/app/data/order_created.txt’ into table order_created_partition PARTITION (event_month=‘2018-11’);
select * from order_created_partition where event_month=‘2018-11’;
可以看出,所谓的分区,是人为定义的,跟业务数据实际上是不是属于该分区没关系,比如将相同的数据分别插入两个分区中,
再比如插入的数据有2017-12月份的和2018-01月份的数据
删除分区:
alter table order_created_partition drop partition (event_month=‘2018-11’);
– 从hdfs中已经看不到event_month=2018-01的分区子目录了
手工创建hdfs目录和文件,添加分区的情况:
静态分区表如果手工创建对应的hdfs目录上传文件,而不使用分区创建命令和load数据到分区的命令,
分区表中无法查到该分区信息,需要刷新,这种添加分区的途径是不合法的
hdfs dfs -mkdir /user/hive/warehouse/hive.db/order_created_partition/event_month=2018-11
hdfs dfs -put order_created.txt /user/hive/warehouse/hive.db/order_created_partition/event_month=2018-11
select * from order_created_partition where event_month=‘2018-11’;
– 此时是查不到该分区的
MSCK REPAIR TABLE order_created_partition; 刷新元数据到MySQL —禁止使用
– 修复表信息之后可以查询
show partitions order_created_partition;
– 查看该表的所有分区
应该采用这种方式添加分区表:
alter table order_created_partition drop partition (event_month=‘2018-12’);
多级分区表:
多级分区表,即创建的时候指定 PARTITIONED BY (event_month string,loc string),
根据顺序,级联创建 event_month=XXX/loc=XXX目录,其他和一级的分区表是一样的
create table order_mulit_partition(
orderNumber string,
event_time string
)PARTITIONED BY(event_month string, step string)
row format delimited fields terminated by ‘\t’;
load data local inpath ‘/home/hadoop/app/data/order_created.txt’ into table order_mulit_partition PARTITION (event_month=‘2018-11’,step=‘1’);
动态分区表:
create table emp_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double)
PARTITIONED BY (deptno int)
row format delimited fields terminated by ‘\t’;
– 根据部门编号分区,原表中的部门编号字段就没有必要创建了
– 而是由分区表创建的伪列来替代
– 设置动态分区模式为非严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
insert into table emp_partition partition(deptno)
select empno,ename,job,mgr,hiredate,sal,comm ,deptno from ruoze_emp;
– 动态分区表的数据插入语句
– partition(deptno) 而不是 partition(deptno=XXX)
– select 子句从原表查出来的列数和列序要和分区表列数和列序保持一致
– select 子句最后一列要为分区表的分区列
– 不在需要where子句
– 设置动态分区模式为非严格模式
– set hive.exec.dynamic.partition.mode=nonstrict;