在刚刚创建的表上插入覆盖

Posted

技术标签:

【中文标题】在刚刚创建的表上插入覆盖【英文标题】:INSERT OVERWRITE on just created table 【发布时间】:2022-01-17 06:45:37 【问题描述】:

我必须为客户复制一个流程。我从未与 Hive 合作过,所以我试图了解他们在其他情况下做了什么。

我试图理解的 Hive 脚本是这个:

DROP TABLE IF EXISTS distribution.030601_TI11;

CREATE EXTERNAL TABLE IF NOT EXISTS distribution.030601_TI11(
    mygroup STRING, year STRING, type1 STRING, type2 STRING,
    type3 STRING, myvalue INT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
STORED AS TEXTFILE LOCATION '/warehouse/distribution/030601_TI11';

INSERT OVERWRITE TABLE distribution.030601_TI11
SELECT *
FROM develop.030601_TI11;

他们在做什么?

据我了解 Hive,在外部表上的 DROP TABLE IF EXISTS 语句只会删除表元数据而不是表数据。但我想知道INSERT OVERWRITE 语句是否删除了存储在表中的先前条目,并仅插入指定位置中包含的新行

另外,LOCATION 是如何管理的?我想从单个 .csv 文件创建表。我可以写LOCATION '/warehouse/develop/myfile.csv' 之类的东西吗,或者我只能提供一个 HDFS 目录作为位置?

【问题讨论】:

【参考方案1】:

你是对的,外部表的位置将保持不变。因此,通过 drop-create 语句,他们确保表在删除或创建之前不存在。而且该表在本质上似乎是动态的,因此这可能是 drop-create 的另一个原因。

请注意您使用的是CREATE EXTERNAL TABLE IF NOT EXISTS,这意味着如果表存在,它将不会重新创建。 将使用 INSERT OVERWRITE 清理和加载存储。 现在,如果你想在 csv 文件上创建一个表,只需使用LOCATION '/warehouse/develop/myfile。您不必在位置中使用 .csv。

【讨论】:

所以对于我最初的问题,INSERT OVERWRITE 正在删除存储在表中的先前条目,并仅插入指定位置中包含的新行? 不是真的,insert overwrite 将清理整个表并将所有内容插入源代码。因此,如果源表中有 100 条记录,目标表中有 5000 条记录,则目标表中的所有内容都将被删除,只有 100 条记录将加载到目标表中。记录是否存在并不重要。你可以假设它就像你写的那样,但它不是那样工作的。【参考方案2】:

INSERT OVERWRITE TABLE 删除表位置内的所有文件并移动新文件。这发生在查询已经成功执行并在临时位置创建结果文件的最后,然后加载任务删除表位置中的所有文件并将文件从临时位置移动到表位置。另请参阅此答案:https://***.com/a/63378038/2700344

如果要在单个文件之上创建表,请将其放在某个文件夹中,并确保同一文件夹中没有其他文件,并将该文件夹指定为创建表 DDL 中的位置。您也可以使用hdfs dfs -put 命令或使用 LOAD 命令或使用其他方式将该文件放入现有表位置。这里的要点是表应该有它自己的位置,无论该位置有多少文件 - 单个文件或多个文件,位置是一个文件夹(目录),而不是一个文件。即使可以在单个文件而不是文件夹上创建表,也是不安全的,因为覆盖可以创建另一个文件,并且表的位置指向不存在的文件。仔细阅读这个问题的答案:How to point to a single file with external table

【讨论】:

以上是关于在刚刚创建的表上插入覆盖的主要内容,如果未能解决你的问题,请参考以下文章

触发器导致在视图中使用的表上插入后,如何进行 MYSQL 视图更新

在我的 PostGres 表上授予所有权限,但在尝试插入/选择时仍然收到“权限被拒绝”错误

在具有聚集列存储索引的表上创建触发器 - 错误

在已有大量数据的表上创建 MySQL 索引

在过程中动态添加的表上创建触发器

mysql在具有1亿行的表上创建索引