1、按天划分的表
即将每天的数据存放在一张表中。
对于Hive,这种情况下应该使用分区表,通过where子句的表达式来选择查询所需要的指定的分区,这样的查询执行效率高。
一个理想的分区方案不应该导致产生太多的分区和文件夹目录,并且每个目录下的文件应该足够的大。
分区过多或者维度过小,会导致产生大量的文件,会超过文件系统的处理能力
两个解决方案:
(1)按照不同的时间粒度来确定合适大小的数据量,可以选择月和日的粒度
(2)使用两个级别的分区并使用不同的维度,例如,第一个分区可能是按天(day)划分的,而二级分区可以是地区(region_code)
create table dmt.test_par_info (
url string,time long,city string
)partitioned by (day int,state string)
2、唯一键和标准化
hive中可以使用 array、map 、struct等类型,来存储多项数据,可以适当减少一些表
3、同一份数据多种处理
from dmt.user_inv_info_mon a
insert into table dmt.user_inv_par_info_mon
partition(region='guangdong')
select * where a.user_id='a019'
insert overwrite table dmt.user_inv_par_info_mon
partition(region='anhui')
select * where a.inv_time='2020/1/1'
4、分桶表数据存储
分桶是将数据集分解成更容易管理的若干部分的另一个技术。
创建分桶表:
create table dmt.user_inv_bucket_info_mon (
user_id string,
inv_time string,
prod_id string,
inv_amt int
)
partitioned by (dt string)
clustered by (user_id) into 50 buckets;
强制hive为目标表的分桶初始化过程设置一个正确的reducer个数
set hive.enforce.bucketing=true;
填充分区
from dmt.user_inv_par_info_mon
insert overwrite table dmt.user_inv_bucket_info_mon
partition(dt='2020-02-23')
select user_id,inv_time,prod_id,inv_amt
分桶有几个优点:
(1)因为桶的数量是固定的,所以它没有数据波动
(2)桶对于抽样再合适不过
(3)分桶同时有利于执行高效的map-side JOIN
5、使用列存储表
hive通常使用行式存储,不过也提供了一个列式serde来以混合列式格式存储信息。若某个字段重复的数据较多,采用列式存储会是最好的方法
6、使用压缩
压缩可以使磁盘上存储的数据量变小,这样可以通过降低I/O来提高查询速度。