如何按所有值对 table 进行分区?

How do I partition a table by all values?

我有一个外部 table,现在我想给它添加分区。我有 224 个唯一的城市 ID,我只想写 alter table my_table add partition (cityid) location /path; 但蜂巢抱怨说我没有为城市 ID 值提供任何东西,它应该是例如alter table my_table add partition (cityid=VALUE) location /path;,但我不想 运行 alter table 对城市 ID 的每个值执行命令,如何一次性对所有 ID 执行此操作?

Hive 命令行如下所示:

hive> alter table pavel.browserdata add partition (cityid) location '/user/maria_dev/data/cityidPartition';                                                                                                                                                                                                           

FAILED: ValidationFailureSemanticException table is not partitioned but partition spec exists: {cityid=null}

物理层面的分区是一个存放数据文件的位置(每个值的单独位置,通常看起来像key=value)。如果你已经有了包含文件的分区目录结构,你只需要在 Hive metastore 中创建分区,然后你可以使用 ALTER TABLE SET LOCATION 将你的 table 指向根目录,然后使用 MSCK REPAIR TABLE 命令. Amazon Elastic MapReduce (EMR) 版本的 Hive 上的等效命令是:ALTER TABLE table_name RECOVER PARTITIONS。这将添加 Hive 分区元数据。请在此处查看手册:RECOVER PARTITIONS

如果您只有未分区 table 数据位于其位置,则添加分区将不起作用,因为需要重新加载数据,您需要:

创建另一个分区table并使用insert overwrite使用动态分区加载加载分区数据:

set hive.exec.dynamic.partition=true;   
set hive.exec.dynamic.partition.mode=nonstrict; 

insert overwrite table2 partition(cityid) 
select col1, ... colN,
       cityid    
  from table1; --partitions columns should be last in the select

这是重组数据的一种非常有效的方法。

在此之后您可以删除源 table 并重命名您的目标 table。