在Hive中创建表时,默认情况下Hive负责管理数据。这意味着Hive把数据移入到它的“仓库目录”。另外一种选择是创建一个“外部表”(external table)。这会让Hive到仓库目录以外的位置去访问数据。
这两种表的区别表现在LOAD和DROP命令的语义上。先来看托管表(managed table)。
加载数据到托管表时,Hive把数据移到仓库目录。例如:
CREATE TABLE managed_table (dummy STRING);
LOAD DATA INPATH '/usr/tom/data.txt' INTO table managed_table;
把文件hdfs://usr/tom/data.txt移到Hive的managed_table表的仓库目录中。即hdfs://user/hive/warehouse/managed_table。
由于加载操作就是文件系统中的文件移动和文件重命名,因此它的执行速度很快。但是,即使是托管表,Hive也并不检查表目录中的文件是否符合为表所声明的模式。如果有数据和模式不匹配,只有在查询时才会知道。我们通常要通过查询为缺失字段返回的空值NULL才知道存在不匹配的行。可以发出一个简单的select语句来查询表中的若干行数据,从而检查数据是否能被正确解析。
如果随后要丢弃一个表,可以使用如下语句:
DROP TABLE managed_table;
这个表,包括它的元数据和数据,会被一起删除。因此,因为最初的LOAD是一个移动操作,而DROP是一个删除操作。所以数据会彻底消失。这就是Hive所谓的“托管数据”的含义。
对于外部表而言,这两个操作的结果就不一样了:由你来控制数据的创建和删除。外部数据的位置需要创建表的时候指明:
CREATE EXTERNAL TABLE external_table (dummy STRING) LOCATION '/usr/tom/external_table';
LOAD DATA INPATH '/usr/tom/data.txt' INTO TABLE external_table;
使用EXTERNAL关键字以后,Hive知道数据并不是自己管理,因此不会把数据移到自己的仓库目录。事实上,在定义时,它甚至不会检查这一外部表位置是否存在。这是一个非常有用的特性,因为它意味着你可以把创建数据推迟到创建表之后才进行。
丢弃外部表时,Hive不会碰数据,只会删除元数据。
那么,应该如何选择使用那种表呢?大都数情况下,这两种方式没有太大的区别(当然DROP语义除外),因此这只是个人喜好问题。作为一个经验法则,如果所有处理都是由Hive完成,应该使用托管表。普遍的用法是把存放在HDFS的初始数据集作外部表进行使用,然后用Hive的变换功能把数据移到托管的Hive表。这一方法反之也成立--外部表可以用于从Hive导出数据供其他程序使用。
————————————————
版权声明:本文为CSDN博主「YQlakers」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yqlakers/article/details/72967684