在上篇文章里胳嘲,我列舉了一個簡單的hive操作實例,創(chuàng)建了一張表test扣草,并且向這張表加載了數(shù)據(jù)了牛,這些操作和關(guān)系數(shù)據(jù)庫操作類似,我們常把hive和關(guān)系數(shù)據(jù)庫進行比較辰妙,也正是因為hive很多知識點和關(guān)系數(shù)據(jù)庫類似鹰祸。
關(guān)系數(shù)據(jù)庫里有表(table),分區(qū)上岗,hive里也有這些東西福荸,這些東西在hive技術(shù)里稱為hive的數(shù)據(jù)模型蕴坪。今天本文介紹hive的數(shù)據(jù)類型肴掷,數(shù)據(jù)模型以及文件存儲格式敬锐。這些知識大家可以類比關(guān)系數(shù)據(jù)庫的相關(guān)知識。
首先我要講講hive的數(shù)據(jù)類型呆瞻。
Hive支持兩種數(shù)據(jù)類型台夺,一類叫原子數(shù)據(jù)類型,一類叫復(fù)雜數(shù)據(jù)類型痴脾。
原子數(shù)據(jù)類型包括數(shù)值型颤介、布爾型和字符串類型,具體如下表所示:
由上表我們看到hive不支持日期類型赞赖,在hive里日期都是用字符串來表示的滚朵,而常用的日期格式轉(zhuǎn)化操作則是通過自定義函數(shù)進行操作。
hive是用java開發(fā)的前域,hive里的基本數(shù)據(jù)類型和java的基本數(shù)據(jù)類型也是一一對應(yīng)的辕近,除了string類型。有符號的整數(shù)類型:TINYINT匿垄、SMALLINT移宅、INT和BIGINT分別等價于java的byte、short椿疗、int和long原子類型漏峰,它們分別為1字節(jié)、2字節(jié)届榄、4字節(jié)和8字節(jié)有符號整數(shù)浅乔。Hive的浮點數(shù)據(jù)類型FLOAT和DOUBLE,對應(yīng)于java的基本類型float和double類型。而hive的BOOLEAN類型相當(dāng)于java的基本數(shù)據(jù)類型boolean铝条。
對于hive的String類型相當(dāng)于數(shù)據(jù)庫的varchar類型童擎,該類型是一個可變的字符串,不過它不能聲明其中最多能存儲多少個字符攻晒,理論上它可以存儲2GB的字符數(shù)顾复。
Hive支持基本類型的轉(zhuǎn)換,低字節(jié)的基本類型可以轉(zhuǎn)化為高字節(jié)的類型鲁捏,例如TINYINT芯砸、SMALLINT、INT可以轉(zhuǎn)化為FLOAT给梅,而所有的整數(shù)類型假丧、FLOAT以及STRING類型可以轉(zhuǎn)化為DOUBLE類型,這些轉(zhuǎn)化可以從java語言的類型轉(zhuǎn)化考慮动羽,因為hive就是用java編寫的包帚。當(dāng)然也支持高字節(jié)類型轉(zhuǎn)化為低字節(jié)類型,這就需要使用hive的自定義函數(shù)CAST了运吓。
復(fù)雜數(shù)據(jù)類型包括數(shù)組(ARRAY)渴邦、映射(MAP)和結(jié)構(gòu)體(STRUCT)疯趟,具體如下表所示:
下面我們看看hive使用復(fù)雜數(shù)據(jù)類型的實例,建表:
查詢語句:
接下來我們來看看hive的數(shù)據(jù)模型谋梭,hive的數(shù)據(jù)模型包括:database信峻、table、partition和bucket瓮床。下面我將一一論述這四種數(shù)據(jù)模型盹舞。
1.Database:相當(dāng)于關(guān)系數(shù)據(jù)庫里的命名空間(namespace),它的作用是將用戶和數(shù)據(jù)庫的應(yīng)用隔離到不同的數(shù)據(jù)庫或模式中隘庄,該模型在hive 0.6.0之后的版本支持踢步,hive提供了create database dbname、use dbname以及drop database dbname這樣的語句丑掺。
2.表(table):hive的表邏輯上由存儲的數(shù)據(jù)和描述表格中的數(shù)據(jù)形式的相關(guān)元數(shù)據(jù)組成贾虽。表存儲的數(shù)據(jù)存放在分布式文件系統(tǒng)里,例如HDFS吼鱼,元數(shù)據(jù)存儲在關(guān)系數(shù)據(jù)庫里蓬豁,當(dāng)我們創(chuàng)建一張hive的表,還沒有為表加載數(shù)據(jù)的時候菇肃,該表在分布式文件系統(tǒng)地粪,例如hdfs上就是一個文件夾(文件目錄)。Hive里的表友兩種類型一種叫托管表琐谤,這種表的數(shù)據(jù)文件存儲在hive的數(shù)據(jù)倉庫里蟆技,一種叫外部表,這種表的數(shù)據(jù)文件可以存放在hive數(shù)據(jù)倉庫外部的分布式文件系統(tǒng)上斗忌,也可以放到hive數(shù)據(jù)倉庫里(注意:hive的數(shù)據(jù)倉庫也就是hdfs上的一個目錄质礼,這個目錄是hive數(shù)據(jù)文件存儲的默認路徑,它可以在hive的配置文件里進行配置织阳,最終也會存放到元數(shù)據(jù)庫里)眶蕉。
下面是創(chuàng)建托管表的實例語句:
大家看到了創(chuàng)建外部表時候table之前要加關(guān)鍵字external,同時還要用location命令指定文件存儲的路徑唧躲,如果不使用locaction數(shù)據(jù)文件也會放置到hive的數(shù)據(jù)倉庫里造挽。如果你對大數(shù)據(jù)開發(fā)感興趣,想系統(tǒng)學(xué)習(xí)大數(shù)據(jù)的話弄痹,可以加入大數(shù)據(jù)技術(shù)學(xué)習(xí)交流扣扣群458345782饭入,私信管理員即可免費領(lǐng)取開發(fā)工具以及入門學(xué)習(xí)資料
這兩種表在使用的區(qū)別主drop命令上,drop是hive刪除表的命令肛真,托管表執(zhí)行drop命令的時候谐丢,會刪除元數(shù)據(jù)和存儲的數(shù)據(jù),而外部表執(zhí)行drop命令時候只刪除元數(shù)據(jù)庫里的數(shù)據(jù),而不會刪除存儲的數(shù)據(jù)乾忱。另外我還要談?wù)劚淼膌oad命令讥珍,hive加載數(shù)據(jù)時候不會對元數(shù)據(jù)進行任何檢查,只是簡單的移動文件的位置饭耳,如果源文件格式不正確串述,也只有在做查詢操作時候才能發(fā)現(xiàn)执解,那個時候錯誤格式的字段會以NULL來顯示寞肖。
3.分區(qū)(partition):hive里分區(qū)的概念是根據(jù)“分區(qū)列”的值對表的數(shù)據(jù)進行粗略劃分的機制,在hive存儲上就體現(xiàn)在表的主目錄(hive的表實際顯示就是一個文件夾)下的一個子目錄衰腌,這個文件夾的名字就是我們定義的分區(qū)列的名字新蟆,沒有實際操作經(jīng)驗的人可能會認為分區(qū)列是表的某個字段,其實不是這樣右蕊,分區(qū)列不是表里的某個字段琼稻,而是獨立的列,我們根據(jù)這個列存儲表的里的數(shù)據(jù)文件饶囚。使用分區(qū)是為了加快數(shù)據(jù)分區(qū)的查詢速度而設(shè)計的帕翻,我們在查詢某個具體分區(qū)列里的數(shù)據(jù)時候沒必要進行全表掃描。下面我就舉一個分區(qū)使用的實例:
我們看到在表logs的目錄下有了兩層子目錄dt=2013-06-02和country=cn
查詢操作:
這個時候我們的查詢操作只會掃描file1.txt和file2.txt文件萝风。
4.桶(bucket):上面的table和partition都是目錄級別的拆分數(shù)據(jù)嘀掸,bucket則是對數(shù)據(jù)源數(shù)據(jù)文件本身來拆分數(shù)據(jù)。使用桶的表會將源數(shù)據(jù)文件按一定規(guī)律拆分成多個文件规惰,要使用bucket睬塌,我們首先要打開hive對桶的控制,命令如下:
下面這段文字是我引用博客園里風(fēng)生水起的博文:
示例:
建臨時表student_tmp歇万,并導(dǎo)入數(shù)據(jù):
hive> descstudent_tmp;????????
OK
id????? int
age???? int
namestring
stat_date?????? string
Timetaken: 0.106 seconds
hive> select* fromstudent_tmp;
OK
1?????? 20????? zxm???? 20120801
2?????? 21????? ljz???? 20120801
3?????? 19????? cds???? 20120801
4?????? 18????? mac???? 20120801
5?????? 22????? android 20120801
6?????? 23????? symbian 20120801
7?????? 25????? wp????? 20120801
Timetaken: 0.123 seconds
建student表:
hive>createtablestudent(id INT, age INT, nameSTRING)
???????>partitioned by(stat_date STRING)
???????>clustered by(id) sorted by(age) into2 bucket
???????>row format delimited fields terminated by',';
設(shè)置環(huán)境變量:
???????>sethive.enforce.bucketing = true;
插入數(shù)據(jù):
???????>fromstudent_tmp
???????>insertoverwrite tablestudent partition(stat_date="20120802")
???????>selectid,age,namewherestat_date="20120801"sort byage;
查看文件目錄:
$ hadoop fs -ls /user/hive/warehouse/studentstat_date=20120802/
Found 2 items
-rw-r--r--?? 1 work supergroup???????? 31 2012-07-31 19:52 /user/hive/warehouse/student/stat_date=20120802/000000_0
-rw-r--r--?? 1 work supergroup???????? 39 2012-07-31 19:52 /user/hive/warehouse/student/stat_date=20120802/000001_0
物理上揩晴,每個桶就是表(或分區(qū))目錄里的一個文件,桶文件是按指定字段值進行hash贪磺,然后除以桶的個數(shù)例如上面例子2硫兰,最后去結(jié)果余數(shù),因為整數(shù)的hash值就是整數(shù)本身寒锚,上面例子里瞄崇,字段hash后的值還是字段本身,所以2的余數(shù)只有兩個0和1壕曼,所以我們看到產(chǎn)生文件的后綴是*0_0和*1_0,文件里存儲對應(yīng)計算出來的元數(shù)據(jù)苏研。
Hive的桶,我個人認為沒有特別的場景或者是特別的查詢腮郊,我們可以沒有必要使用摹蘑,也就是不用開啟hive的桶的配置。因為桶運用的場景有限轧飞,一個是做map連接的運算衅鹿,我在后面的文章里會講到撒踪,一個就是取樣操作了,下面還是引用風(fēng)生水起博文里的例子:
查看sampling數(shù)據(jù):
hive> select* fromstudent tablesample(bucket 1 outof2 onid);??????????????????????????????????????????????????????????????????????????????
Total MapReduce jobs = 1
Launching Job 1 outof1
.......
OK
4?????? 18????? mac???? 20120802
2?????? 21????? ljz???? 20120802
6?????? 23????? symbian 20120802
Timetaken: 20.608 seconds
tablesample是抽樣語句大渤,語法:TABLESAMPLE(BUCKET x OUTOFy)
y必須是table總bucket數(shù)的倍數(shù)或者因子制妄。hive根據(jù)y的大小,決定抽樣的比例泵三。例如耕捞,table總共分了64份,當(dāng)y=32時烫幕,抽取 (64/32=)2個bucket的數(shù)據(jù)俺抽,當(dāng)y=128時,抽取(64/128=)1/2個bucket的數(shù)據(jù)较曼。x表示從哪個bucket開始抽取磷斧。例 如,table總bucket數(shù)為32捷犹,tablesample(bucket 3 outof16)弛饭,表示總共抽取(32/16=)2個bucket的數(shù)據(jù)萍歉,分別為第3個bucket和第(3+16=)19個bucket的數(shù)據(jù)侣颂。
好了,今天就寫到這里了翠桦,明天要上班不能在加班寫文章了横蜒。這篇博文的內(nèi)容并沒有寫完(hive存儲格式?jīng)]有寫),因為這個章節(jié)的知識非常重要是理解hive的關(guān)鍵销凑,所以要講的細點丛晌,明天我爭取寫完hive存儲格式的文章,后天也就是本周二斗幼,我將為我們技術(shù)部門介紹hive的相關(guān)技術(shù)澎蛛,寫博文算是我的預(yù)演了。
最后我要講一下自己對大數(shù)據(jù)技術(shù)的看法蜕窿,我覺得大數(shù)據(jù)技術(shù)是一個跨時代的技術(shù)谋逻,是互聯(lián)網(wǎng)技術(shù)的未來,也是云計算的未來桐经,它的深入發(fā)展不僅僅是數(shù)據(jù)處理上毁兆,也會改變整個互聯(lián)網(wǎng)技術(shù)的生態(tài)鏈,包括我們使用的技術(shù)和開發(fā)語言阴挣,很慶幸親身經(jīng)歷著整個偉大時代的變革气堕,我也要展開雙臂迎接這個大時代的到來。