繁体   English   中英

Hive,如何按具有 null 值的列进行分区,将所有空值放在一个分区中

[英]Hive, how to partition by a colum with null values, putting all nulls in one partition

我使用的是 Hive,而 IDE 是色调。 我正在尝试为我的分区键选择不同的组合键。

我的原始表的定义如下:

CREATE External Table `my_hive_db`.`my_table`(
    `col_id` bigint,
    `result_section__col2` string,
    `result_section_col3` string ,
    `result_section_col4` string,
    `result_section_col5` string,
    `result_section_col6__label` string,
    `result_section_col7__label_id` bigint ,
    `result_section_text` string ,
    `result_section_unit` string,
    `result_section_col` string ,
    `result_section_title` string,
    `result_section_title_id` bigint,
    `col13` string,
    `timestamp` bigint,
    `date_day` string
    )
    PARTITIONED BY ( 
      `date_year` string, 
      `date_month` string)
    ROW FORMAT SERDE 
      'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
    STORED AS INPUTFORMAT 
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
    OUTPUTFORMAT 
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
    LOCATION
      's3a://some/where/in/amazon/s3'; 

上面的代码工作正常。 但是当我使用 date_day 作为分区键创建一个新表时,该表是空的,我需要运行 MSCK 修复表。 但是,我收到以下错误:

编译语句时出错:FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.ddl.DDLTask

在此处输入图像描述

当分区键为 date_year、date_month 时,MSCK 工作正常。

我收到错误的表的表定义如下:

CREATE External Table `my_hive_db`.`my_table`(
    `col_id` bigint,
    `result_section__col2` string,
    `result_section_col3` string ,
    `result_section_col4` string,
    `result_section_col5` string,
    `result_section_col6__label` string,
    `result_section_col7__label_id` bigint ,
    `result_section_text` string ,
    `result_section_unit` string,
    `result_section_col` string ,
    `result_section_title` string,
    `result_section_title_id` bigint,
    `col13` string,
    `timestamp` bigint,
    `date_year` string, 
    `date_month` string
  )
    PARTITIONED BY (
     `date_day` string)
    ROW FORMAT SERDE 
      'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
    STORED AS INPUTFORMAT 
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
    OUTPUTFORMAT 
      'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
    LOCATION
      's3a://some/where/in/amazon/s3'; 

在此之后,以下查询为空:

Select * From `my_hive_db`.`my_table` Limit 10;

因此,我运行了以下命令:

MSCK REPAIR TABLE `my_hive_db`.`my_table`;

我收到错误:编译语句时出错:FAILED:执行错误,从 org.apache.hadoop.Z8A4AC216FB230DATask3834DE641B3E5D0F7Z.dldl.ql 返回代码 1。

我检查了这个链接,因为这正是我得到的错误,但是通过使用提供的解决方案:

set hive.msck.path.validation=ignore;
MSCK REPAIR TABLE table_name;

我得到一个不同的错误:

处理语句时出错:无法在运行时修改 hive.msck.path.validation。 它不在允许在运行时修改的参数列表中。

我认为我收到这些错误的原因是 date_day 有超过 2 亿条记录具有 null 值。

有 31 个不同的日期日期,而不是 null 值。 我想用 32 个分区对我的表进行分区,每个分区都有一个不同的 date_day 字段值,并且所有 null 值都进入不同的分区。 有没有办法这样做(按具有 null 值的列分区)?

如果这可以通过spark实现,我也愿意使用它。

这是通过重新创建表来更改分区键的更大问题的一部分,如在回答我的另一个问题的链接中提到的那样

谢谢您的帮助。

您似乎不明白 Hive 的分区是如何工作的。 Hive 将数据存储到 HDFS(或 S3,或其他一些分布式文件夹)上的文件中。 如果您创建一个名为my_schema.my_table的非分区 parquet 表,您将在分布式存储中看到存储在文件夹中的文件

hive/warehouse/my_schema.db/my_table/part_00001.parquet
hive/warehouse/my_schema.db/my_table/part_00002.parquet
...

如果您创建一个按列p_col分区的表,文件将如下所示

hive/warehouse/my_schema.db/my_table/p_col=value1/part_00001.parquet
hive/warehouse/my_schema.db/my_table/p_col=value1/part_00002.parquet
...
hive/warehouse/my_schema.db/my_table/p_col=value2/part_00001.parquet
hive/warehouse/my_schema.db/my_table/p_col=value2/part_00002.parquet
...

命令MSCK repair table允许您在创建外部表时自动重新加载分区。

假设您在 s3 上有如下所示的文件夹:

hive/warehouse/my_schema.db/my_table/p_col=value1/part_00001.parquet
hive/warehouse/my_schema.db/my_table/p_col=value2/part_00001.parquet
hive/warehouse/my_schema.db/my_table/p_col=value3/part_00001.parquet

您创建一个外部表

CREATE External Table my_schema.my_table(
   ... some columns ...
)
PARTITIONED BY (p_col STRING)

该表将被创建但为空,因为 Hive 尚未检测到分区。 您运行MSCK REPAIR TABLE my_schema.my_table ,Hive 将识别出您的分区p_col与 s3 ( /p_col=value1/ ) 上的分区方案匹配。

根据我从您的其他问题中了解到的情况,您正试图通过执行更改表的分区方案

CREATE External Table my_schema.my_table(
   ... some columns ...
)
PARTITIONED BY (p_another_col STRING)

并且您收到一条错误消息,因为p_another_col与 s3 中使用的列p_col不匹配。 这个错误是完全正常的,因为你所做的没有意义。

另一个问题的答案所述,您需要使用不同的分区方案创建第一个表的副本。

你应该尝试这样的事情:

CREATE External Table my_hive_db.my_table_2(
    `col_id` bigint,
    `result_section__col2` string,
    `result_section_col3` string ,
    `result_section_col4` string,
    `result_section_col5` string,
    `result_section_col6__label` string,
    `result_section_col7__label_id` bigint ,
    `result_section_text` string ,
    `result_section_unit` string,
    `result_section_col` string ,
    `result_section_title` string,
    `result_section_title_id` bigint,
    `col13` string,
    `timestamp` bigint,
    `date_year` string, 
    `date_month` string
)
PARTITIONED BY (`date_day` string)

然后用动态分区填充你的新表

INSERT OVERWRITE TABLE my_hive_db.my_table_2 PARTITION(date_day)
SELECT 
  col_id,
  result_section__col2,
  result_section_col3,
  result_section_col4,
  result_section_col5,
  result_section_col6__label,
  result_section_col7__label_id,
  result_section_text,
  result_section_unit,
  result_section_col,
  result_section_title,
  result_section_title_id,
  col13,
  timestamp,
  date_year,
  date_month,
  date_day
FROM my_hive_db.my_table_1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM