Hive:内部表与外部表

内部表&外部表

未被external修饰的是内部表(managed table),被external修饰的为外部表(external table);

可以使用命令DESCRIBE FORMATTED table_name标识托管表或外部表,该命令将根据表类型显示 MANAGED_TABLEEXTERNAL_TABLE

区别

  • 内部表数据由Hive自身管理,外部表数据由HDFS管理;

    导入数据时,内部表会把导入目录下的数据文件移动到自己的数据仓库目录下,Hive自身管理;外部表不会移动文件,数据由HDFS管理。

  • 内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定;

    默认位置可以被location属性覆盖。一般数据文件已经存在或位于远程位置时,使用外部表。

  • 删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;

  • 使用truncate 清空表数据:内部表会删除数据文件,外部表会直接报错,不允许清空表数据

  • 对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name

补充说明:

  • 对于内部表,由于加载操作就是文件系统中的文件移动和文件重命名,因此它的执行速度很快。但是,即使是托管表,Hive也并不检查表目录中的文件是否符合为表所声明的模式。如果有数据和模式不匹配,只有在查询时才会知道。我们通常要通过查询为缺失字段返回的空值NULL才知道存在不匹配的行。可以发出一个简单的select语句来查询表中的若干行数据,从而检查数据是否能被正确解析。
  • 对于内部表,因为最初的LOAD是一个移动操作,而DROP是一个删除操作。所以数据会彻底消失。这就是Hive所谓的“托管数据”的含义。
  • 那么,应该如何选择使用那种表呢?大都数情况下,这两种方式没有太大的区别(当然DROP语义除外),因此这只是个人喜好问题。作为一个经验法则,如果所有处理都是由Hive完成,应该使用托管表。普遍的用法是把存放在HDFS的初始数据集作外部表进行使用,然后用Hive的变换功能把数据移到托管的Hive表。这一方法反之也成立–外部表可以用于从Hive导出数据供其他程序使用。

互相转换

TBLPROPERTIES (“EXTERNAL”=”TRUE”) in release 0.6.0+ (HIVE-1329 (opens new window)) – Change a managed table to an external table and vice versa for “FALSE”.将托管表更改为外部表,反之亦然,则为“FALSE”

EXTERNAL:通过修改此属性可以实现内部表和外部表的转化。

修改内部表为外部表

1
alter table tablename set tblproperties('EXTERNAL'='TRUE')

修改外部表为内部表

1
alter table tablename set tblproperties('EXTERNAL'='FALSE')

注意:(‘EXTERNAL’=‘TRUE’)和(‘EXTERNAL’=‘FALSE’)为固定写法,区分大小写!

托管表与外部表

Introduction

该文档列出了两者之间的某些差异,但是基本的区别是 Hive 假定它拥有托管表的数据。这意味着数据,其属性和数据布局将并且只能通过 Hive 命令进行更改。数据仍然存在于正常的文件系统中,没有任何事情阻止您更改它而无需告知 Hive。如果这样做确实违反了 Hive 的不变性和期望,则可能会看到不确定的行为。

另一个结果是数据被附加到 Hive 实体。因此,每当您更改实体(例如删除表)时,数据也会更改(在这种情况下,数据将被删除)。这与传统的 RDBMS 非常相似,在传统的 RDBMS 中,您也不会自行管理数据文件,而是使用基于 SQL 的访问权限来操作数据文件。

对于外部表,Hive 假定它不管理数据。

可以使用命令DESCRIBE FORMATTED table_name标识托管表或外部表,该命令将根据表类型显示 MANAGED_TABLEEXTERNAL_TABLE

Statistics可以在内部和外部表及分区上进行 Management 以优化查询。

Feature comparison

这意味着有很多功能仅适用于两种表类型之一,而不适用于另一种。这是不完整的清单:

  • ARCHIVE/UNARCHIVE/TRUNCATE/MERGE/CONCATENATE 仅适用于托管表
  • DROP 删除托管表的数据,而只删除外部表的元数据
  • ACID /事务处理仅适用于托管表
  • 查询结果缓存仅适用于托管表
  • 外部表仅允许 RELY 约束
  • 某些物化视图功能仅适用于托管表

Managed tables

托管表存储在hive.metastore.warehouse.dirpath 属性下,默认情况下存储在类似于/user/hive/warehouse/databasename.db/tablename/的文件夹路径中。在表创建期间,默认位置可以被location属性覆盖。如果删除了托管表或分区,则将删除与该表或分区关联的数据和元数据。如果未指定 PURGE 选项,则数据将在定义的持续时间内移至废纸 trash 文件夹。

当 Hive 需要管理表的生命周期(所有处理都需要由Hive完成)或生成临时表时,请使用托管表。

External tables

外部表描述了外部文件上的元数据/架构。外部表文件可以由 Hive 外部的进程访问和管理。外部表可以访问存储在诸如 Azure 存储卷(ASV)或远程 HDFS 位置的源中的数据。如果更改了外部表的结构或分区,则可以使用MSCK REPAIR TABLE table_name语句刷新元数据信息。

当文件已经存在或位于远程位置时,请使用外部表,并且即使表已删除,文件也应保留。

参考链接:

https://cwiki.apache.org/confluence/display/Hive/Managed+vs.+External+Tables

https://blog.csdn.net/YQlakers/article/details/72967684