如何通过(仅)时间戳列的一部分对配置单元表进行分区?

nle07wnf  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(342)

假设我有一个配置单元表,其中包含一个timestamp列,该列经常(几乎总是)包含在查询的where子句中。用timestamp字段划分这个表是有意义的;然而,为了保持一个合理的基数,按天划分(而不是按时间戳的最大分辨率)是有意义的。
实现这一目标的最佳方法是什么?我应该在上面创建一个额外的列(日期)和分区吗?或者有没有一种方法可以在不创建重复列的情况下实现分区?

kmbjn2e3

kmbjn2e31#

由于分区也是配置单元中的列之一,所以每个分区都有值(使用静态或动态分区进行赋值),并且每个分区都Map到hdfs中的目录,因此它必须是附加的列。
您可以选择以下选项之一:
假设ddl表: CREATE TABLE temp( id string) PARTITIONED BY (day int) 如果数据是按天组织的,则添加静态分区: ALTER TABLE xyz ADD PARTITION (day=00) location '/2017/02/02'; 或者 INSERT OVERWRITE TABLE xyz PARTITION (day=1) SELECT id FROM temp  WHERE dayOfTheYear(**timestamp**)=1; 使用动态分区生成天数: INSERT INTO TABLE xyz PARTITION (day) SELECT id , dayOfTheYear(day) FROM temp; Hive里没有 dayOfTheYear 你创建的函数。

w7t8yxp5

w7t8yxp52#

它不是一个新列,而是一个伪列,您应该通过添加如下分区规范来重新创建表:

create table table_name (
  id                int,
  name              string,
  timestamp         string
)
partitioned by (date string)

然后像这样动态地加载创建分区的数据

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
FROM table_name_old tno
INSERT OVERWRITE TABLE table_name PARTITION(substring(timestamp,0,10))
       SELECT tno.id, tno.name, tno.timestamp;

现在,如果您从表中选择all,您将看到分区的一个新列,但是考虑到配置单元分区只是一个子目录,而不是一个实列,因此它不会影响表的总大小(只有千字节)。

相关问题