Hive内部表和外部表有什么区别?

125

有谁可以告诉我Hive的外部表和内部表之间的区别。我知道这个区别在删除表时会体现出来。但是我不理解为什么在内部表中数据和元数据都被删除,而在外部表中只有元数据被删除。有人能用节点的术语来解释一下吗?

19个回答

127
有一个关系型数据库在主节点上,用于跟踪状态。 例如,当你使用CREATE TABLE FOO(foo string) LOCATION 'hdfs://tmp/';创建一个表时,该表的模式被存储在数据库中。
如果你有一个分区表,分区将存储在数据库中(这样Hive就可以使用分区列表而不必去文件系统中查找它们等)。这些都是“元数据”。
当你删除内部表时,它会删除数据和元数据。
当你删除外部表时,它只会删除元数据。这意味着现在Hive不再知道该数据。它不会触及数据本身。

13
如果您删除一张表,Hive 会返回删除之前该表的状态。如果在删除 'foo' 表后运行查询 'select * from foo',Hive 将告诉您该表不存在。这是因为您已经让 Hive 忘记了该表。数据仍然存在于其所在的文件系统中。可以将元数据看作指向数据位置的“指针”。 - prestomation
1
所以您的意思是,如果我有数据在此位置opt / nancy / foo.txt,并将其加载到外部表中并删除它,则元数据会丢失,但是此位置opt / nancy / foo.txt中的数据仍然存在? - NJ_315
好的,现在这个位置是在HDFS还是我的本地系统中?如果它在本地系统中,当我将数据加载到内部表中并删除表时,文件foo.txt仍将保留在该位置。到目前为止,我是正确的吗? - NJ_315
3
Hive表存储在支持的文件系统上(如Hbase、HDFS、S3等)。我假设您正在使用“LOAD DATA”将数据从本地文件加载到Hive表中?在这种情况下,您正在将本地文件复制到Hive表中。当您删除此表时,内部表中的数据副本将被删除,但是来自“LOAD DATA”命令的源文件仍将保持完好。 - prestomation
我有一些奇怪的行为:当我删除内部表时,有时候它的HDFS目录仍然存在。但其他时候则不会。我正在尝试以不同用户(HDFS和Impala)运行Hive shell,但我还没有找到规律。是否有某种定期运行的刷新守护程序? - Matthew Cornell
显示剩余2条评论

104

Hive表可以创建为EXTERNAL或INTERNAL。这是一个选择,影响数据的加载、控制和管理。

当满足以下条件时,请使用EXTERNAL表:

  1. 数据也在Hive之外使用。例如,数据文件被现有程序读取和处理,该程序不锁定文件。
  2. 在DROP TABLE后需要保留数据在基础位置中。如果您将多个模式(表或视图)指向单个数据集,或者如果您正在遍历各种可能的模式,则可以应用此方法。
  3. 要使用自定义位置,例如ASV。
  4. Hive不应拥有数据和控制设置、目录等,您有另一个程序或进程将执行这些操作。
  5. 您不是基于现有表创建表(AS SELECT)。

当满足以下条件时,请使用INTERNAL表:

数据是临时的。

您希望Hive完全管理表和数据的生命周期。


3
请参阅链接,了解有关HDInsight Hive内部和外部表的介绍。 - Anonymous Person
创建一个内部表会删除HDFS中的数据,还是只是复制并专门用于Hive,保留源(HDFS)不变? - luckyluke
@swetha 你好,我来这里是因为我完全删除了metastore.db,但数据仍然存在于hdfs上。所以当我执行show tables时,没有显示任何内容。有重新创建元数据的方法吗? - awadhesh14

55

回答你的问题:

对于外部表,Hive将数据存储在创建表时指定的位置中(通常不在仓库目录中)。如果删除外部表,则表元数据将被删除但数据不会被删除。

对于内部表,Hive将数据存储在其仓库目录中。如果删除该表,则表元数据和数据都将被删除。


供参考:

内部表和外部表的区别:

对于外部表-

  • 外部表在HDFS服务器上存储文件,但表与源文件没有完全连接。

  • 如果删除外部表,则文件仍然保留在HDFS服务器上。

    例如,如果使用HIVE-QL在HIVE中创建名为“table_test”的外部表并将表链接到文件“file”,则从HIVE删除“table_test”不会从HDFS中删除“file”。

  • 任何可访问HDFS文件结构的人都可以访问外部表文件,因此安全性需要在HDFS文件/文件夹级别进行管理。

  • 元数据由主节点维护,从HIVE中删除外部表仅会删除元数据而不会删除数据/文件。


对于内部表-

  • 基于hive.metastore.warehouse.dir中的设置存储在一个目录中,默认情况下,内部表存储在以下目录中:“/user/hive/warehouse”,您可以通过更新配置文件中的位置来更改它。
  • 删除表会从主节点和HDFS分别删除元数据和数据。
  • 仅使用HIVE控制内部表文件安全性。安全性需要在HIVE中进行管理,可能在模式级别进行(取决于实现)。
Hive 可以使用内部或外部表,这是一种选择,会影响数据的加载、控制和管理方式。 当以下情况出现时,请使用外部表:
  • 数据也被 Hive 之外的程序使用。例如,数据文件由一个现有程序读取和处理,该程序不锁定文件。
  • 数据需要保留在底层位置,即使 DROP TABLE 后仍然存在。如果您将多个模式(表或视图)指向单个数据集,或者如果您正在遍历各种可能的模式,则可以应用此设置。
  • Hive 不应拥有数据和控制设置、目录等内容,您可能有另一个程序或进程来执行这些任务。
  • 您不是基于现有表(AS SELECT)创建表。
当以下情况出现时,请使用内部表:
  • 数据是临时的。
  • 希望 Hive 完全管理表和数据的生命周期。
来源:

HDInsight: Hive Internal and External Tables Intro

Internal & external tables in Hadoop- HIVE


4
@CapturedTree的回答是不正确的。"Hive moves data into its warehouse directory." 这句话完全是错误的,它并没有这样做。数据存储在表的位置上,无论是外部表还是管理表都一样。 - leftjoin

6

内部表数据存储在仓库文件夹中,而外部表数据存储在表创建时所指定的位置。

因此,当您删除内部表时,会同时删除位于仓库文件夹下的模式以及数据,但对于外部表而言,只有模式会被删除。

如果您要重新获取已删除的外部表,可以再次创建具有相同模式的表,并将其指向原始数据位置。希望现在清楚了。


5
根据我有限的研究和测试结果(使用Hive 1.1.0 -cdh5.12.0),行为上(而不是预期用途上)唯一的区别似乎在于删除表时:
  • 内部(托管)表的数据会从HDFS文件系统中删除
  • 外部表的数据不会从HDFS文件系统中删除。

(注意:请参阅“托管和外部表”部分,网址为https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL,其中列出了我没有完全理解的其他差异)

我相信Hive会基于以下优先顺序从上到下选择需要创建表的位置:

  1. 在表创建期间定义的位置
  2. 在创建表的数据库/模式中定义的位置。
  3. Hive默认仓库目录(hive.site.xml中的属性hive.metastore.warehouse.dir)

当在“创建Hive表”的过程中未使用“Location”选项时,将使用上述优先规则。这适用于内部和外部表。这意味着内部表不一定必须驻留在仓库目录中,可以驻留在任何其他地方。

注:可能会有一些场景我没有涉及到,但根据我的有限探索,内部表和外部表的行为似乎相同,除了上述的一个差异(数据删除)。我尝试了以下场景,对于内部和外部表都进行了测试:

  1. 创建带有和不带有Location选项的表
  2. 创建带有和不带有分区选项的表
  3. 使用Hive Load和Insert语句添加新数据
  4. 在Hive之外的表位置添加数据文件(使用HDFS命令)并使用“MSCK REPAIR TABLE”命令刷新表
  5. 删除表

很好的探索。这是唯一解释Hive如何处理内部和外部表位置选项的答案。 - d2207197

3
在外部表中,如果您删除表,则仅会删除该表的模式,表数据存在于物理位置中。因此,要删除数据,请使用hadoop fs - rmr tablename命令。 管理表Hive将完全控制表格。在外部表中,用户将对其进行控制。

我遇到了这样一种情况:在通过CREATE TABLE foo (id INT)创建的内部表上执行DROP TABLE后,目录并不总是被删除。元数据显然没问题,因为SHOW TABLES是一致的——在删除后,该表不会出现在列表中。令人困惑的是,我注意到有时候目录确实被删除了,但我无法始终重现这种情况。有什么想法吗? - Matthew Cornell
表的权限是否已经检查?您可能已经将HDFS上的位置所有权更改为其他用户。 - Milind Jindal

1
此外请记住,Hive是一个大型数据仓库。当您想要删除表时,您不希望丢失千兆字节或万亿字节的数据。在那个规模上生成、移动和复制数据可能需要很长时间。 当您删除“管理”表时,Hive也会删除其数据。 当您删除“外部”表时,只会从Hive元存储中删除模式定义。 HDFS上的数据仍然存在。

1

外部hive表的优点在于删除表时不会删除文件,我们可以设置不同的行格式,如serde....delimited


1
考虑以下适用于外部表的场景:
一个MapReduce (MR) 作业过滤一个巨大的日志文件以输出n个子日志文件(例如,每个子日志文件都包含特定类型的日志消息),并将输出即n个子日志文件存储在HDFS中。
这些日志文件需要加载到Hive表中以进行进一步的分析,在这种情况下,我建议使用外部表,因为实际的日志文件由外部进程生成和拥有,即MR作业,此外,您还可以避免将每个生成的日志文件加载到相应的Hive表中的额外步骤。

1

如果您希望Hive管理数据的完整生命周期(包括删除),则内部表非常有用;而当文件在Hive之外使用时,外部表非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接