Hive本身并不存儲(chǔ)數(shù)據(jù),而是將數(shù)據(jù)存儲(chǔ)在Hadoop的HDFS中躬拢,表名對(duì)應(yīng)HDFS中的目錄/文件躲履。根據(jù)數(shù)據(jù)的不同存儲(chǔ)方式,將Hive表分為外部表聊闯、內(nèi)部表工猜、分區(qū)表和分桶表四種數(shù)據(jù)模型。每種數(shù)據(jù)模型各有優(yōu)缺點(diǎn)馅袁。通過(guò)create user命令創(chuàng)建user表時(shí)域慷,會(huì)在HDFS中生成一個(gè)user目錄/文件荒辕。
外部表
數(shù)據(jù)不由Hive管理汗销,使用drop命令刪除一個(gè)表時(shí),只是把表的元數(shù)據(jù)給刪除了抵窒,而表的數(shù)據(jù)不會(huì)刪除弛针。 創(chuàng)建外部表的SQL語(yǔ)句:
create external table bigdata17_user(
userid int,
username string,
fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';
在hive的命令行中執(zhí)行show tables;
sql語(yǔ)句,會(huì)看到bigdata17_user的表李皇。
通過(guò)執(zhí)行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user
命令削茁,可以看到在HDFS中有一個(gè)bigdata17_user的目錄宙枷。這時(shí)候文件夾下面是沒(méi)有數(shù)據(jù)的,因?yàn)檫€沒(méi)有導(dǎo)入數(shù)據(jù)茧跋。bigdata17.db是數(shù)據(jù)庫(kù)名慰丛,hive默認(rèn)的數(shù)據(jù)庫(kù)是default。
執(zhí)行SQL語(yǔ)句:load data inpath '/data/user.csv' overwrite into table bigdata17_user;
導(dǎo)入數(shù)據(jù)到bigdata17_user表中瘾杭。
執(zhí)行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user
命令诅病,就看到該目錄下面有個(gè)user.csv的文件。
通過(guò)drop table bigdata17_user
;語(yǔ)句刪除表粥烁。
然后執(zhí)行show tables語(yǔ)句贤笆,發(fā)現(xiàn)該表已經(jīng)不存在。
我們?cè)俅螆?zhí)行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user
讨阻,發(fā)現(xiàn)bigdata17_user目錄還存在芥永,目錄中還有user.csv文件。
通過(guò)上述的操作钝吮,驗(yàn)證了使用drop刪除表時(shí)是不會(huì)刪除外部表的數(shù)據(jù)埋涧。而我們要恢復(fù)外部表只需再次執(zhí)行創(chuàng)建bigdat17_user表的SQL即可:
create external table bigdata17_user(
userid int,
username string,
fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';
內(nèi)部表
內(nèi)部表(有些人會(huì)翻譯成管理表)的數(shù)據(jù)由hive管理,當(dāng)使用drop刪除表時(shí)奇瘦,會(huì)把表的元數(shù)據(jù)和數(shù)據(jù)一起刪除飞袋,數(shù)據(jù)無(wú)法恢復(fù),因此一定要慎用drop刪除內(nèi)部表链患。
創(chuàng)建內(nèi)部表的sql語(yǔ)句:
create table bigdata17_user( userid int, username string, fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';
和外部表創(chuàng)建的語(yǔ)法基本一樣巧鸭,只是創(chuàng)建外部表需要使用external關(guān)鍵字。沒(méi)有external關(guān)鍵字則是創(chuàng)建內(nèi)部表麻捻。
分區(qū)表
內(nèi)部表和外部表都可以使用分區(qū)的功能纲仍,使用分區(qū)的內(nèi)部或外部表稱為分區(qū)表。 創(chuàng)建分區(qū)表的語(yǔ)句:
create external table bigdata17_user_partition(
username string,
fullname string)
partitioned by(userid string)
row format delimited fields terminated by ','
lines terminated by '\n';
往分區(qū)表導(dǎo)入數(shù)據(jù)分為靜態(tài)分區(qū)導(dǎo)入和動(dòng)態(tài)分區(qū)導(dǎo)入贸毕,靜態(tài)分區(qū)是在導(dǎo)入語(yǔ)句中指定分區(qū)值郑叠,例如:
insert overwrite table bigdata17-user_parttion
partition(userid=1)
select username ,fullname from bigdata17_user;
該語(yǔ)句的分區(qū)值默認(rèn)是1,如果有多個(gè)分區(qū)值明棍,必須寫多個(gè)sql語(yǔ)句乡革,效率低下。
一般情況在我們都是使用動(dòng)態(tài)分區(qū)導(dǎo)入數(shù)據(jù)摊腋,
在導(dǎo)入數(shù)據(jù)之前必須執(zhí)行下面的兩條語(yǔ)句讓hive支持動(dòng)態(tài)分區(qū)功能沸版,默認(rèn)是不支持動(dòng)態(tài)分區(qū)的。
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;
動(dòng)態(tài)分區(qū)導(dǎo)入數(shù)據(jù)的sql語(yǔ)句:
insert overwrite table bigdata17_user_partition
partition(userid)
select username ,fullname,userid from bigdata17_user;
我們來(lái)看下分區(qū)表的數(shù)據(jù)在hdfs中是以何種形式組織存放的兴蒸,執(zhí)行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user_partition
命令视粮,會(huì)看到下圖的內(nèi)容:
因?yàn)閎igdata17_user_partition表是按照userid字段進(jìn)行分區(qū)的,bigdata17_user_partition一共有1橙凳、2和3的三個(gè)數(shù)值蕾殴,因此有3個(gè)文件笑撞。由此可見(jiàn),分區(qū)字段有多少個(gè)不同的值钓觉,就有幾個(gè)文件茴肥。相同分區(qū)的數(shù)據(jù)存放在同一個(gè)文件中。
注意:在使用insert overwrite table select方式導(dǎo)入數(shù)據(jù)到分區(qū)表時(shí)荡灾,有多個(gè)分區(qū)字段時(shí)炉爆,分區(qū)partition中的字段順序必須和select字段的順序一致。
分桶表
分桶是將某個(gè)字段取哈希值卧晓,值相同的數(shù)據(jù)分發(fā)到一個(gè)桶中芬首。在創(chuàng)建分桶表的時(shí)候必須指定分桶的字段,并且指定要分桶的數(shù)量逼裆。 創(chuàng)建分桶表對(duì)SQL語(yǔ)句如下:
create table bigdata17_user_bucket( userid int, username string, fullname string)
clustered by(userid) into 2 buckets
row format delimited fields terminated by ','
lines terminated by '\n';
導(dǎo)入數(shù)據(jù)到bigdata17_user_bucket分桶表中的步驟: 1. 設(shè)置使用分桶屬性:set hive.enforce.bucketing = true郁稍。
2. 執(zhí)行SQL語(yǔ)句
sql insert overwrite table bigdata17_user_bucket select userid,username ,fullname from bigdata17_user;
執(zhí)行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user_bucket
命令,會(huì)看到bigdata17_user_bucket目錄中有兩個(gè)文件胜宇。
其中userid為1和3的數(shù)據(jù)寫入到000001_0文件中耀怜,userid為2的數(shù)據(jù)寫入到000000_0的文件中。
注意:分區(qū)和分桶都是按字段來(lái)組織數(shù)據(jù)的存放桐愉,分區(qū)是相同的字段值存放在一個(gè)文件中财破,而分桶是字段哈希值相同的數(shù)據(jù)存放在一個(gè)文件中。