1)建表时通过partitioned by(col_name col_type),hive的分别区字段使用的是外字段.
2)hive的分区,区分大小写
3)hive的分区本质是在表目录下面创建目录。但是该分区字段只是一个伪列,不真实存在于数据文件中。但是select * 直接能显示该列.
4)一个表就可以有一个或多个分区,分区下面也可以有一个或多个分区。
1)可以在select时指定分区,让用户在做数据分析时缩小数据扫描的范围,提高查询效率。
2)用户可以自己定义目录结构,对目录结构的使用具有更多灵活性。
hive的分区功能是很有意义的,因为hive通常要对数据进行全盘扫描来满足查询条件,通过创建很多分区其实可以优化一些查询。
HDFS被设计用于存储百万个大文件,而非十亿个小文件。使用过多的分区可能导致一个问题:会创建大量的文件和文件夹。一个分区就对应着包含多个文件的文件夹,如果一个表存在数百个分区,那么每天可能会创建好几万个文件。这样如果持续很久,那么最终能超出NameNode对系统元数据信息的处理能力。因为NameNode必须要将所有文件系统的元数据信息都保存在内存中,虽然每个文件只需要少量字节大小的元数据,但这样也会限制一个HDFS实例所能管理的文件总数的上限。
一个理想的分区方案不应该导致产生太多的分区目录。并且每个目录下的文件应该足够大,应该是文件系统中块的若干倍。
在我们使用理想的方案时,可以使分区内的文件保持足够大,从而优化一般情况下查询数据的吞吐量,同时有必要考虑这种粒度级别在未来是否适用,特别是查询中where子句选择较小粒度的范围的情况。
另一种解决方案是使用二级分区并且使用不同的维度。例如:第一个分区可能按天(day)进行划分,而二级分区可能通过如州名(state)这样的地理区域进行划分。
然而一些州可能会比其他州的数据多,用户会发现MapTask在处理数据时出现了不均匀的情况,这是因为处理大的数据量比处理小的数据量花费的时间多,这时候可以考虑分桶。
静态分区:加载数据时指定分区值
动态分区:数据未知,根据分区的值创建分区(关闭严格模式)
混合分区:静态分区和动态分区都有
1]通过load data的形式加载,如:
load data local inpath "xxx" into table t1 partition(year="2022",month="09",day="29");
2]通过insert into的形式加载,如:
insert into t1 partition(year="2022",month="09",day="29") select id,name from tmp;
1]不可通过load data的形式加载
2]通过创建临时表 insert into的形式加载数据
- set hive.exec.dynamic.partition=true;
- set hive.exec.dynamic.partition.mode=nonstrict;
- #设置为非严格模式,如果是严格模式,则必须至少指定一个分区的值,(dt='xxx',...)
- insert into tmp.tmp_nginx_pv_hour2 partition(dt,hour,dn)
- select * from tmp.tmp_nginx_pv_hour where dt="20191201" and hour="06";
-
- insert overwrite table tmp.tmp_nginx_pv_hour2 partition(dt,hour,dn)
- select * from tmp.tmp_nginx_pv_hour where dt="20191201" and hour="06";
- #这样写比较好,可以分区内覆盖,运行错了可以重新运行,注意insert into和insert overwrite table。前者没有table,后者有table.
1】不可使用load data的形式加载数据
2】通过insert into的形式加载数据
insert into t3 parition(year="2018",month) select uid,name,uage,month from t3;
二.分桶表技术意义
在单个分区表中,当不能更细粒度的划分数据时,会采用分桶技术将数据更加细粒度的划分和管理。
a]隔离数据,优化查询
set mapreduce.job.reduces=-1;
b]因为桶的数量固定,所以没有数据波动,桶对于抽样再合适不过
C]分桶同时有利于执行高效的map-side join
桶的概念就是MapReduce中分区的概念,两者完全相同。物理上每个桶就是目录的同一个文件。一个作业产生的桶(输出文件)数量和reduce任务个数相同。
分区针对的是为实际数据分文件夹。分桶针对的是切分数据数据。
1】要想实现分桶表,必须设置:
set hive.enforce.bucketing=true;
2】设置hive转化成mapreduce程序,mapreduce程序个数为系统自动分配的数量。
注:配置文件中默认为1
set mapreduce.job.reduces=-1;
3】创建分桶表
- create table stu_bucket(
- id int,
- name string
- )
- clustered by (id) into 4 buckets
- row format delimited
- fields terminated by "\t"
- ;
4】导入数据
这种方式无法导入数据
load data local inpath "xxx" into table stu_bucket;
有效的方式:
a)创建临时表
- create table stu(
- id int,
- name string
- )
- row format delimited
- fields terminated by "\t"
- ;
b)在临时表中插数据
load data local inpath "xxx" into table stu;
c)用select将临时表的数据导入到分桶表
insert into table stu_bucket select * from stu;