前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hive 内部表与外部表

Hive 内部表与外部表

作者头像
smartsi
发布2019-08-07 08:58:55
3.1K0
发布2019-08-07 08:58:55
举报
文章被收录于专栏:SmartSiSmartSi

托管表(内部表)和外部表是Hive中的两种不同类型的表,在这篇文章中,我们将讨论Hive中表的类型以及它们之间的差异以及如何创建这些表以及何时将这些表用于特定的数据集。

1. 内部表

托管表(Managed TABLE)也称为内部表(Internal TABLE)。这是Hive中的默认表。当我们在Hive中创建一个表,没有指定为外部表时,默认情况下我们创建的是一个内部表。如果我们创建一个内部表,那么表将在HDFS中的特定位置创建。默认情况下,表数据将在HDFS/usr/hive/warehouse目录中创建。如果我们删除了一个内部表,那么这个表的表数据和元数据都将从HDFS中删除。

1.1 创建表

我们可以用下面的语句在Hive里面创建一个内部表:

代码语言:javascript
复制
CREATE  TABLE IF NOT EXISTS tb_station_coordinate(
  station string,
  lon string,
  lat string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';

我们已经成功创建了表并使用如下命令检查表的详细信息:

代码语言:javascript
复制
hive> describe formatted tb_station_coordinate;
OK
# col_name            	data_type           	comment             

station             	string              	                    
lon                 	string              	                    
lat                 	string              	                    

# Detailed Table Information	 	 
Database:           	default             	 
Owner:              	xiaosi              	 
CreateTime:         	Tue Dec 12 17:42:09 CST 2017	 
LastAccessTime:     	UNKNOWN             	 
Retention:          	0                   	 
Location:           	hdfs://localhost:9000/user/hive/warehouse/tb_station_coordinate	 
Table Type:         	MANAGED_TABLE       	 
Table Parameters:	 	 
	COLUMN_STATS_ACCURATE	{\"BASIC_STATS\":\"true\"}
	numFiles            	0                   
	numRows             	0                   
	rawDataSize         	0                   
	totalSize           	0                   
	transient_lastDdlTime	1513071729          

# Storage Information	 	 
SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe	 
InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
Compressed:         	No                  	 
Num Buckets:        	-1                  	 
Bucket Columns:     	[]                  	 
Sort Columns:       	[]                  	 
Storage Desc Params:	 	 
	field.delim         	,                   
	serialization.format	,                   
Time taken: 0.16 seconds, Fetched: 33 row(s)

从上面我们可以看到表的类型Table TypeMANAGED_TABLE,即我们创建了一个托管表(内部表)。

1.2 导入数据

我们使用如下命令将一个样本数据集导入到表中:

代码语言:javascript
复制
hive> load data local inpath '/home/xiaosi/station_coordinate.txt' overwrite into table tb_station_coordinate;
Loading data to table default.tb_station_coordinate
OK
Time taken: 2.418 seconds

如果我们在HDFS的目录/user/hive/warehouse/tb_station_coordinate查看,我们可以得到表中的内容:

代码语言:javascript
复制
xiaosi@yoona:~$ hadoop fs -ls  /user/hive/warehouse/tb_station_coordinate
Found 1 items
-rwxr-xr-x   1 xiaosi supergroup        374 2017-12-12 17:50 /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
xiaosi@yoona:~$
xiaosi@yoona:~$
xiaosi@yoona:~$ hadoop fs -text  /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
桂林北站,110.302159,25.329024
杭州东站,120.213116,30.290998
山海关站,119.767555,40.000793
武昌站,114.317576,30.528401
北京南站,116.378875,39.865052
...

> /home/xiaosi/station_coordinate.txt是本地文件系统路径。从上面的输出我们可以看到数据是从本地的这个路径复制到HDFS上的/user/hive/warehouse/tb_station_coordinate/目录下。 为什么会自动复制到HDFS这个目录下呢?这个是由Hive的配置文件设置的。在Hive${HIVE_HOME}/conf/hive-site.xml配置文件中指定,hive.metastore.warehouse.dir属性指向的就是Hive表数据存放的路径(在这配置的是/user/hive/warehouse/)。Hive每创建一个表都会在hive.metastore.warehouse.dir指向的目录下以表名创建一个文件夹,所有属于这个表的数据都存放在这个文件夹里面/user/hive/warehouse/tb_station_coordinate

1.3 删除表

现在让我们使用如下命令删除上面创建的表:

代码语言:javascript
复制
hive> drop table tb_station_coordinate;
Moved: 'hdfs://localhost:9000/user/hive/warehouse/tb_station_coordinate' to trash at: hdfs://localhost:9000/user/xiaosi/.Trash/Current
OK
Time taken: 1.327 seconds

从上面的输出我们可以得知,原来属于tb_station_coordinate表的数据被移到hdfs://localhost:9000/user/xiaosi/.Trash/Current文件夹中(如果你的Hadoop没有采用回收站机制,那么删除操作将会把属于该表的所有数据全部删除)(回收站机制请参阅:Hadoop Trash回收站使用指南)。

如果我们在HDFS的目录/user/hive/warehouse/tb_station_coordinate查看:

代码语言:javascript
复制
xiaosi@yoona:~$ hadoop fs -ls  /user/hive/warehouse/tb_station_coordinate
ls: `/user/hive/warehouse/tb_station_coordinate': No such file or directory

你可以看到输出为No such file or directory,因为表及其内容都从HDFS从删除了。

2. 外部表

当数据在Hive之外使用时,创建外部表(EXTERNAL TABLE)来在外部使用。无论何时我们想要删除表的元数据,并且想保留表中的数据,我们使用外部表。外部表只删除表的schema

2.1 外部普通表

我们使用如下命令创建一个外部表:

代码语言:javascript
复制
CREATE EXTERNAL TABLE IF NOT EXISTS tb_station_coordinate(
  station string,
  lon string,
  lat string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';

我们现在已经成功创建了外部表。我们使用如下命令检查关于表的细节:

代码语言:javascript
复制
hive> describe formatted tb_station_coordinate;
OK
# col_name            	data_type           	comment             

station             	string              	                    
lon                 	string              	                    
lat                 	string              	                    

# Detailed Table Information	 	 
Database:           	default             	 
Owner:              	xiaosi              	 
CreateTime:         	Tue Dec 12 18:16:13 CST 2017	 
LastAccessTime:     	UNKNOWN             	 
Retention:          	0                   	 
Location:           	hdfs://localhost:9000/user/hive/warehouse/tb_station_coordinate	 
Table Type:         	EXTERNAL_TABLE      	 
Table Parameters:	 	 
	COLUMN_STATS_ACCURATE	{\"BASIC_STATS\":\"true\"}
	EXTERNAL            	TRUE                
	numFiles            	0                   
	numRows             	0                   
	rawDataSize         	0                   
	totalSize           	0                   
	transient_lastDdlTime	1513073773          

# Storage Information	 	 
SerDe Library:      	org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe	 
InputFormat:        	org.apache.hadoop.mapred.TextInputFormat	 
OutputFormat:       	org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat	 
Compressed:         	No                  	 
Num Buckets:        	-1                  	 
Bucket Columns:     	[]                  	 
Sort Columns:       	[]                  	 
Storage Desc Params:	 	 
	field.delim         	,                   
	serialization.format	,                   
Time taken: 0.132 seconds, Fetched: 34 row(s)

从上面我们可以看到表的类型Table TypeEXTERNAL_TABLE,即我们创建了一个外部表。

2.2 导入数据

我们使用如下命令将一个样本数据集导入到表中:

代码语言:javascript
复制
hive> load data local inpath '/home/xiaosi/station_coordinate.txt' overwrite into table tb_station_coordinate;
Loading data to table default.tb_station_coordinate
OK
Time taken: 2.418 seconds

如果我们在HDFS的目录/user/hive/warehouse/tb_station_coordinate查看,我们可以得到表中的内容:

代码语言:javascript
复制
xiaosi@yoona:~$ hadoop fs -ls  /user/hive/warehouse/tb_station_coordinate
Found 1 items
-rwxr-xr-x   1 xiaosi supergroup        374 2017-12-12 18:19 /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
xiaosi@yoona:~$
xiaosi@yoona:~$
xiaosi@yoona:~$ hadoop fs -text  /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
桂林北站,110.302159,25.329024
杭州东站,120.213116,30.290998
山海关站,119.767555,40.000793
武昌站,114.317576,30.528401
...
2.3 删除表

现在让我们使用如下命令删除上面创建的表:

代码语言:javascript
复制
hive> drop table tb_station_coordinate;
OK
Time taken: 0.174 seconds
hive>

我们的Hadoop已经开启了回收站机制,但是删除操作并没有将数据进行删除,不像删除内部表一样,输出Moved: 'hdfs://localhost:9000/user/hive/warehouse/tb_station_coordinate' to trash at: hdfs://localhost:9000/user/xiaosi/.Trash/Current(回收站机制请参阅:Hadoop Trash回收站使用指南)。为了验证我们真的没有删除数据,我们在HDFS目录下查看数据:

代码语言:javascript
复制
xiaosi@yoona:~$ hadoop fs -ls  /user/hive/warehouse/tb_station_coordinate
Found 1 items
-rwxr-xr-x   1 xiaosi supergroup        374 2017-12-12 18:19 /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
xiaosi@yoona:~$
xiaosi@yoona:~$ hadoop fs -text  /user/hive/warehouse/tb_station_coordinate/station_coordinate.txt
桂林北站,110.302159,25.329024
杭州东站,120.213116,30.290998
山海关站,119.767555,40.000793
武昌站,114.317576,30.528401
北京南站,116.378875,39.865052
...

你可以看到表中的数据仍然在HDFS中。所以我们得知如果我们创建一个外部表,在删除表之后,只有与表相关的元数据被删除,而不会删除表的内容。

2.4 创建表指定外部目录

只有当你的数据在/user/hive/warehouse目录中时,上述方法才能有效。但是,如果你的数据在另一个位置,如果你删除该表,数据也将被删除。所以在这种情况下,你需要在创建表时设置数据的外部位置,如下所示:

代码语言:javascript
复制
CREATE EXTERNAL TABLE IF NOT EXISTS tb_station_coordinate(
  station string,
  lon string,
  lat string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '/user/xiaosi/test/coordinate/';

备注: 你也可以通过在创建表时设置数据存储位置来创建一个内部表。但是,如果删除表,数据将被删除。 如果你想要创建外部表,需要在创建表的时候加上 EXTERNAL 关键字,同时指定外部表存放数据的路径(例如2.4所示),也可以不指定外部表的存放路径(例如2.3所示),这样Hive将在HDFS上的/user/hive/warehouse/目录下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里。

3. 使用场景

3.1 内部表
  • 数据是临时的
  • 希望使用Hive来管理表和数据的生命周期
  • 删除后不想要数据
3.2 外部表
  • 这些数据也在Hive之外使用。
  • Hive不管理数据和权限设置以及目录等,需要你有另一个程序或过程来做这些事情
  • 不是基于现有表(AS SELECT)来创建的表
  • 可以创建表并使用相同的模式并指向数据的位置
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 内部表
    • 1.1 创建表
      • 1.2 导入数据
        • 1.3 删除表
        • 2. 外部表
          • 2.1 外部普通表
            • 2.2 导入数据
              • 2.3 删除表
                • 2.4 创建表指定外部目录
                • 3. 使用场景
                  • 3.1 内部表
                    • 3.2 外部表
                    相关产品与服务
                    大数据
                    全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档