Hive 理解配置单元表创建符号

Hive 理解配置单元表创建符号,hive,create-table,hive-partitions,hiveddl,Hive,Create Table,Hive Partitions,Hiveddl,我遇到了一些配置单元表,需要将它们转换为Redshift/MySql等价物。 我在理解配置单元查询结构时遇到困难,请提供帮助: CREATE TABLE IF NOT EXISTS table_1 ( id BIGINT, price DOUBLE, asset string ) PARTITIONED BY ( pt STRING ); ALTER TABLE table_1 DROP IF EXISTS PARTITION (pt== '${yyyymmdd}

我遇到了一些配置单元表,需要将它们转换为Redshift/MySql等价物。 我在理解配置单元查询结构时遇到困难,请提供帮助:

CREATE TABLE IF NOT EXISTS table_1 (
    id BIGINT,
    price DOUBLE,
    asset string
)
PARTITIONED BY (
    pt STRING
);
ALTER TABLE table_1 DROP IF EXISTS PARTITION (pt== '${yyyymmdd}');

INSERT OVERWRITE TABLE table_1 PARTITION (pt= '${yyyymmdd}') 
select aa.id,aa.price,aa.symbol from
...
...
from
 table_2 table 
我很难理解PARTITIONED BY子句。如果我理解正确的话,这与MySQL表分区不同,是特定于配置单元的动态分区。 分区不定义列或键,按当前日期进行分区

这是否意味着表_1按日期划分?每天都有一个单独的分区

随后在代码中有类似于

inner join table_new table on table.pt = '${yyyymmdd}' and ...
在此上下文中,是否意味着只有插入到
yyyyymmdd
上的行被选择用于联接


谢谢。

默认情况下,配置单元中的分区是HDFS中的一个文件夹,其名称为
key=value
+元数据位于配置单元元存储中。您可以更改分区位置并在任何文件夹的顶部创建分区

分区依据(pt字符串)
定义类型为字符串的分区列pt,而不是日期。分区值存储在元数据中。pt列不存在于表数据文件中,它仅在PARTITIONED BY中定义,所有分区值都存储在元数据中。如果动态加载分区,则将创建名为pt='value'的分区文件夹

这句话动态创建分区:

INSERT OVERWRITE TABLE table_1 PARTITION (pt) 
select id, price, symbol
       coln as pt            --partition column should be the last one
  from ...
这句话加载单个静态分区:

INSERT OVERWRITE TABLE table_1 PARTITION (pt= '${yyyymmdd}') 
select aa.id,aa.price,aa.symbol 
  from
未选择任何分区列,分区值在

PARTITION  (pt= '${yyyymmdd}')
'${yyyyymmdd}
这里有一个名为
yyyymmdd
的参数,它使用
--hivevar
传递给脚本,如下所示:

 hive --hivevar yyyymmdd=20200604 -f myscript.sql 
在这种情况下,您可以将任何字符串作为分区值传递,尽管参数名yyyymmdd表明它的格式


顺便说一句,配置单元中的日期格式是
'yyyy-MM-dd'
格式中的字符串可以隐式转换为日期

我将尝试一次性解释什么是Hive中的分区。首先是

何时使用表分区

  • 表分区在以下情况下是好的:

    • 读取整个数据集花费的时间太长
    • 查询几乎总是在分区列上进行过滤
    • 分区列有合理数量的不同值
  • ETL过程的数据生成按文件名或目录名拆分数据

  • 分区列值不在数据本身中
  • 不要对具有许多唯一值的列进行分区
  • 示例:按名字对客户进行分区
创建分区表

要创建分区表,请在CREATETABLE语句中使用PARTITED BY子句。 必须指定分区列的名称和类型 在PARTITIONED BY子句中,并且仅在PARTITIONED BY子句中。 它们也不得出现在所有其他列的列表中

CREATE TABLE customers_by_country 
        (cust_id STRING, name STRING) 
PARTITIONED BY (country STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
上面显示的示例CREATETABLE语句按国家创建表customers\u, 它由名为country的字符串列进行分区。 请注意,country列仅出现在PARTITIONED BY子句中, 而不是在上面的列列表中。 本例仅指定一个分区列,但可以使用 PARTITIONED BY子句中以逗号分隔的列列表。 除了这些特定的差异之外,这个CREATETABLE语句是相同的 作为用于创建等效非分区表的语句

表分区的实现方式基本上是透明的 发送给使用配置单元发出查询的用户。 分区列称为虚拟列,因为其值不存储在数据文件中。 以下是按国家/地区对客户执行的
描述
命令的结果;
它显示分区列country,就像它是表中的普通列一样。
您可以在SELECT语句的任何常用子句中引用分区列

name    type    comment

cust_id string   
name    string   
country string   
可以动态或静态加载分区表中的数据

使用动态分区加载数据

将数据加载到分区表的一种方法是使用动态分区, 它在加载数据时使用分区列中的值自动定义分区。 (另一种方法是使用静态分区手动定义分区)

要使用动态分区,必须使用INSERT语句加载数据。 在INSERT语句中,必须使用PARTITION子句列出分区列。 插入的数据必须包含分区列的值。 分区列必须是要插入的数据中最右边的列, 它们的顺序必须与在PARTITION子句中出现的顺序相同

INSERT OVERWRITE TABLE customers_by_country 
    PARTITION(country)
    SELECT cust_id, name, country FROM customers;
上面显示的示例使用INSERT…SELECT语句 通过动态分区将数据加载到customers_by_country表中。 请注意,分区列country包含在内 在PARTITION子句中,并在SELECT列表中最后指定

当配置单元执行此语句时,它会自动创建分区 并根据country列中的值将数据加载到这些分区中。 分区子目录中的结果数据文件不包括country列的值。 由于国家是根据数据文件所在的子目录确定的, 在数据文件中包含国家值也是多余的

查看客户按国家/地区目录的内容。 它现在应该为country列中的每个值都有一个子目录

  • 查看其中一个目录中的文件。 请注意,该文件包含来自该国家/地区的客户的行, 没有其他人;还请注意,未包括国家/地区值
  • 注意:蜂箱包括一个安全功能,可防止
    SET hive.exec.dynamic.partition.mode=nonstrict;
    
    ALTER TABLE customers_by_country
    ADD PARTITION (country='pk');
    
    INSERT OVERWRITE TABLE customers_by_country 
        PARTITION(country='pk')
        SELECT cust_id, name FROM customers WHERE country='pk'