假设我有一个配置单元表,其中包含一个timestamp列,该列经常(几乎总是)包含在查询的where子句中。用timestamp字段划分这个表是有意义的;然而,为了保持一个合理的基数,按天划分(而不是按时间戳的最大分辨率)是有意义的。实现这一目标的最佳方法是什么?我应该在上面创建一个额外的列(日期)和分区吗?或者有没有一种方法可以在不创建重复列的情况下实现分区?
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 你创建的函数。
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;
dayOfTheYear
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,您将看到分区的一个新列,但是考虑到配置单元分区只是一个子目录,而不是一个实列,因此它不会影响表的总大小(只有千字节)。
2条答案
按热度按时间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
你创建的函数。w7t8yxp52#
它不是一个新列,而是一个伪列,您应该通过添加如下分区规范来重新创建表:
然后像这样动态地加载创建分区的数据
现在,如果您从表中选择all,您将看到分区的一个新列,但是考虑到配置单元分区只是一个子目录,而不是一个实列,因此它不会影响表的总大小(只有千字节)。