我想在Hadoop上创建一个包含现有文件分区的表。我需要分区的日期值在文件中可用,但是datevalue列位置不是最后一个。它在中间。如何创建相同的表?
以下是样本:
1 John 2012-01-10 Miller
2 Austin 2012-02-22 Powers
答案 0 :(得分:9)
我们举一个示例:您希望拥有一个分区的配置单元表,其中包含三列(id INT, fname STRING, dt STRING, lname STRING)
,其中id
,fname
,lname
是存储整数ID的列,字符串名字和字符串姓氏respecitlyly和dt是字符串类型的分区列,其中包含yyyy-MM-dd格式的日期。要创建这样的表,您将发出如下命令:
CREATE EXTERNAL TABLE my_table (id INT, fname STRING, lname STRING)
PARTITIONED BY (dt STRING)
LOCATION '/usr/hive/warehouse/my_table';
当您将数据插入此表时(例如,通过INSERT OVERWRITE命令)并检查HDFS位置(/ usr / hive / warehouse / my_table),您会发现数据存储在目录中;每个分区一个目录。目录的名称类似于 dt = 2012-01-01 或 dt = 2012-02-22 。这些目录中的内容将是您选择存储的任何格式的实际数据。分区列不与此数据一起存储;它是一个虚拟列,它会从您的数据所在的分区目录中解密。
现在让我们回答你的问题。由于分区列是一个虚拟列,因此不能将分区的Hive表放在数据之上(无论您的待分区列是存在于文件的中间还是末尾)。您需要在HDFS中存在适当的目录结构才能使分区正常工作。您可能希望创建一个未分区的临时表。
CREATE EXTERNAL TABLE my_table_staging (id INT, fname STRING, dt STRING, lname STRING)
LOCATION '/usr/hive/warehouse/my_table_staging';
然后使用此临时表作为源,使用动态分区填充分区表。您可以使用如下所示的命令:
INSERT OVERWRITE TABLE my_table PARTITION (dt)
SELECT id, fname, lname, dt FROM my_table_staging;
此命令将从临时表中读取数据并将其插入分区表,在HDFS上为您创建适当的目录结构。
参考文献: - https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL - https://cwiki.apache.org/Hive/dynamicpartitions.html