hive內部表、外部表、分區
內部表(managed table)
- 默認創建的是內部表(managed table),存儲位置在
hive.metastore.warehouse.dir
設置,默認位置是/user/hive/warehouse
。
- 導入數據的時候是將文件剪切(移動)到指定位置,即原有路徑下文件不再存在
- 刪除表的時候,數據和元數據都將被刪除
- 默認創建的就是內部表
create table xxx (xx xxx)
外部表(external table)
- 外部表文件可以在外部系統上,只要有訪問權限就可以
- 外部表導入文件時不移動文件,僅僅是添加一個metadata
- 刪除外部表時原數據不會被刪除
- 分辨外部表內部表可以使用
DESCRIBE FORMATTED table_name
命令查看
- 創建外部表命令添加一個external即可,即
create external table xxx (xxx)
- 外部表指向的數據發生變化的時候會自動更新,不用特殊處理
表分區(Partitioned table)
- 有些時候數據是有組織的,比方按日期/類型等分類,而查詢數據的時候也經常只關心部分數據,比方說我只想查2017年8月8號,此時可以創建分區
- 使用
partioned by (xxx)
來創建表的分區,比方說
create table table_name (
id int,
dtDontQuery string,
name string
)
partitioned by (date string)
- 注意,假如table里有date字段,那么分區的時候不要用date了,不然當查詢的時候寫
where data=xxx
時會出錯,即下面這種情況:
create table table_name (
id int,
date string,
name string
)
partitioned by (date string)
- 盡量不用date這個字,根據系統設置不同,可能會觸發不同的錯誤,如
FAILED: ParseException line 3:16 Failed to recognize predicate 'date'. Failed rule: 'identifier' in column specification
,有的時候又遇不到,換一個詞就好了
- 外部表創建時也可以直接指定路徑,但是此時就只能加載一個數據源了,不推薦使用
例子
create table test(name string);
LOAD DATA INPATH '/hdfs_home/20170808' INTO TABLE test partition(date='20170808');
或
create table test_3 (name string, age int) partitioned by (date string) row format delimited fields terminated by ',' lines terminated by '\n';
LOAD DATA INPATH '/hdfs_home/20170808' INTO TABLE test partition(date='20170808'); # 指向文件夾即可
# 執行后原hdfs路徑下20170808文件夾已經不存在(被移動走了)
hive> create external table test_4 (name string, age int) partitioned by (date string) row format delimited fields terminated by ',' lines terminated by '\n';
OK
Time taken: 0.121 seconds
hive> alter table test_4 add partition (date='20170809') location '/hdfs_home/20170809/';
OK
hive> select * from test_4 where date = '20170809';
OK
zhao 14 20170809
# 此時/hdfs_home/20170809還在原路徑下
# 若使用以下命令進行操作,則相當於內部表的操作了,即原路徑文件消失
alter table test_4 add partition (date='20170809');
load data inpath ('/hdfs_home/20170809/') into table test_4 partition (date='20170809')
show partitions table_name;
describe extended tablename;
or
desc formatted tablename;
ALTER TABLE table_name DROP PARTITION (day='20140722');
參考