背景:
有个hive的表,是月分区的(month_id),分区字段用的是string类型。数据量比较大,为了保证计算性能,所以把数据导入到SR里,构建一个内部表。但是在建表的时候想使用月分区使用partition by date_trunc('month', month_id),遇到一个问题,month_id在hive里是string类型并且是yyyyMM的格式,无法顺利建表。
解决方案:
建表语句:
CREATE TABLE `dws_m_topic_datausage_inc` (
`gender` VARCHAR(10) COMMENT '性别',
`age_group` VARCHAR(255) COMMENT '年龄段',
`car_body_type` VARCHAR(255) COMMENT '车身类型',
`car_year` VARCHAR(255) COMMENT '车龄',
`phone_city` VARCHAR(255) COMMENT '手机号归属地',
`phone_province` VARCHAR(255) COMMENT '手机号归属地匹配省份',
`phone_city_level` VARCHAR(255) COMMENT '手机号城市等级',
`month_id` varchar(255) comment '保留原始表的分区字段',
`par_month` DATE COMMENT '月分区格式yyyyMM'
)
DUPLICATE KEY(iccid,vin)
partition by date_trunc('month', par_month )
PROPERTIES (
"replication_num" = "3",
xxxx
xxxx
);
为了保证数据不产生歧义,决定保留month_id这个hive里的原始的分区字段,但是为了保证查询的效率,得有一个分区字段。所以新增了一个par_month字段。
查看分区信息:
表里数据:
数据同步:
使用的是broker 的方式来的
load label dataproducts.dws_m_topic_datausage_inc_202412022124_label(
data infile("hdfs://xxxxx/warehouse/tablespace/external/hive/xxxxxx/month_id=202411/*")
into table dws_m_topic_datausage_inc
format as "orc"
(gender, age_group, car_body_type, car_year, phone_city, phone_province, phone_city_level)
columns from path as (month_id) -- 这里只能是month_id ,否则会报错,因为这个是跟hdfs的路径对应的
set (par_month=str_to_date(concat(month_id,'01'),'%Y%m%d')) -- 这里就是我们的分区字段
)
with broker 'broker1'
(
"timeout" = "3600",
"username" = "bigdata",
"password" = "1234",
"dfs.ha.namenodes.zwkjsc" = "nn1,nn2",
"dfs.namenode.rpc-address.zwkjsc.nn1" = "hdfs://xxxx/zwkj-zsgd-ubd04:8020",
"dfs.namenode.rpc-address.zwkjsc.nn2" = "hdfs://xxxx/zwkj-zsgd-ubd05:8020",
"dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
)
划重点:
- columns from path as (month_id) -- 这里只能是month_id ,否则会报错,因为这个是跟hdfs的路径对应的
- set (par_month=str_to_date(concat(month_id,'01'),'%Y%m%d')) -- 这里就是我们的分区字段,处理成了每个月的第一天,查询的时候要注意限定是yyyyMM01
数据查询:
但我们做数据查询的时候其实我们的par_month是 20241201这个格式。就是代表了202412月份。
select * from xxx partition p202412
或者
select * from xxx where par_monht='20241201'