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

How can I partition a hive table by (only) a portion of a timestamp column?

假设我有一个 Hive table,其中包含一个 TIMESTAMP 列,该列经常(几乎总是)包含在查询的 WHERE 子句中。按 T​​IMESTAMP 字段划分此 table 是有意义的;但是,为了保持合理的基数,按天分区(而不是按 TIMESTAMP 的最大分辨率)是有意义的。

实现此目标的最佳方法是什么?我应该在上面创建一个额外的列(DATE)和分区吗?或者有没有办法在不创建重复列的情况下实现分区?

由于分区也是hive中的列之一,每个分区都有值(使用静态或动态分区分配)并且每个分区都映射到HDFS中的目录,因此它必须是附加列。


您可以选择以下选项之一:

假设 table DDL:

CREATE TABLE temp( id string) PARTITIONED BY (day int)

  1. 如果数据按天组织,则添加静态分区:

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;

  1. 使用动态分区生成天数:

INSERT INTO TABLE xyz PARTITION (day) SELECT id , dayOfTheYear(day) FROM temp;

Hive 没有您创建的任何 dayOfTheYear 函数。

它不是一个新列,而是一个 pseudo-column,您应该 re-create 您的 table 添加分区规范,如下所示:

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;

现在,如果您 select 全部来自您的 table,您将看到该分区的一个新列,但考虑到 Hive 分区只是一个子目录,而不是一个真正的列,因此它不会仅影响几千字节的总 table 大小。