Hive 理解配置单元表创建符号
我遇到了一些配置单元表,需要将它们转换为Redshift/MySql等价物。 我在理解配置单元查询结构时遇到困难,请提供帮助: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}
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过程的数据生成按文件名或目录名拆分数据
- 分区列值不在数据本身中
- 不要对具有许多唯一值的列进行分区
- 示例:按名字对客户进行分区
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'