如何通过(仅)时间戳列的一部分对配置单元 table 进行分区?
How can I partition a hive table by (only) a portion of a timestamp column?
假设我有一个 Hive table,其中包含一个 TIMESTAMP 列,该列经常(几乎总是)包含在查询的 WHERE 子句中。按 TIMESTAMP 字段划分此 table 是有意义的;但是,为了保持合理的基数,按天分区(而不是按 TIMESTAMP 的最大分辨率)是有意义的。
实现此目标的最佳方法是什么?我应该在上面创建一个额外的列(DATE)和分区吗?或者有没有办法在不创建重复列的情况下实现分区?
由于分区也是hive中的列之一,每个分区都有值(使用静态或动态分区分配)并且每个分区都映射到HDFS中的目录,因此它必须是附加列。
您可以选择以下选项之一:
假设 table 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
函数。
它不是一个新列,而是一个 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 大小。
假设我有一个 Hive table,其中包含一个 TIMESTAMP 列,该列经常(几乎总是)包含在查询的 WHERE 子句中。按 TIMESTAMP 字段划分此 table 是有意义的;但是,为了保持合理的基数,按天分区(而不是按 TIMESTAMP 的最大分辨率)是有意义的。
实现此目标的最佳方法是什么?我应该在上面创建一个额外的列(DATE)和分区吗?或者有没有办法在不创建重复列的情况下实现分区?
由于分区也是hive中的列之一,每个分区都有值(使用静态或动态分区分配)并且每个分区都映射到HDFS中的目录,因此它必须是附加列。
您可以选择以下选项之一:
假设 table 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
函数。
它不是一个新列,而是一个 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 大小。