大數據時代的技術hive:hive的數據類型和數據模型

在上篇文章裏,我列舉了一個簡單的hive操做實例,建立了一張表test,而且向這張表加載了數據,這些操做和關係數據庫操做相似,咱們常把hive和關係數據庫進行比較,也正是由於hive不少知識點和關係數據庫相似。html

  關係數據庫裏有表(table),分區,hive裏也有這些東西,這些東西在hive技術裏稱爲hive的數據模型。今天本文介紹hive的數據類型,數據模型以及文件存儲格式。這些知識你們能夠類比關係數據庫的相關知識。java

  首先我要講講hive的數據類型。android

  Hive支持兩種數據類型,一類叫原子數據類型,一類叫複雜數據類型。sql

  原子數據類型包括數值型、布爾型和字符串類型,具體以下表所示:數據庫

基本數據類型數組

類型分佈式

描述函數

示例oop

TINYINT大數據

1個字節(8位)有符號整數

1

SMALLINT

2字節(16位)有符號整數

1

INT

4字節(32位)有符號整數

1

BIGINT

8字節(64位)有符號整數

1

FLOAT

4字節(32位)單精度浮點數

1.0

DOUBLE

8字節(64位)雙精度浮點數

1.0

BOOLEAN

true/false

true

STRING

字符串

‘xia’,」xia」

 

  由上表咱們看到hive不支持日期類型,在hive裏日期都是用字符串來表示的,而經常使用的日期格式轉化操做則是經過自定義函數進行操做。

  hive是用java開發的,hive裏的基本數據類型和java的基本數據類型也是一一對應的,除了string類型。有符號的整數類型:TINYINT、SMALLINT、INT和BIGINT分別等價於java的byte、short、int和long原子類型,它們分別爲1字節、2字節、4字節和8字節有符號整數。Hive的浮點數據類型FLOAT和DOUBLE,對應於java的基本類型float和double類型。而hive的BOOLEAN類型至關於java的基本數據類型boolean。

  對於hive的String類型至關於數據庫的varchar類型,該類型是一個可變的字符串,不過它不能聲明其中最多能存儲多少個字符,理論上它能夠存儲2GB的字符數。

  Hive支持基本類型的轉換,低字節的基本類型能夠轉化爲高字節的類型,例如TINYINT、SMALLINT、INT能夠轉化爲FLOAT,而全部的整數類型、FLOAT以及STRING類型能夠轉化爲DOUBLE類型,這些轉化能夠從java語言的類型轉化考慮,由於hive就是用java編寫的。固然也支持高字節類型轉化爲低字節類型,這就須要使用hive的自定義函數CAST了。

  複雜數據類型包括數組(ARRAY)、映射(MAP)和結構體(STRUCT),具體以下表所示:

複雜數據類型

類型

描述

示例

ARRAY

一組有序字段。字段的類型必須相同

Array(1,2)

MAP

一組無序的鍵/值對。鍵的類型必須是原子的,值能夠是任何類型,同一個映射的鍵的類型必須相同,值得類型也必須相同

Map(‘a’,1,’b’,2)

STRUCT

一組命名的字段。字段類型能夠不一樣

Struct(‘a’,1,1,0)

 

下面咱們看看hive使用複雜數據類型的實例,建表:

Create  table  complex(col1 ARRAY< INT >,
Col2 MAP<STRING, INT >,
Col3 STRUCT<a:STRING,b : INT ,c: DOUBLE >);

  

查詢語句:

Select  col1[0],col2[‘b’],col3.c from  complex;

  

  接下來咱們來看看hive的數據模型,hive的數據模型包括:database、table、partition和bucket。下面我將一一論述這四種數據模型。

1.Database:至關於關係數據庫裏的命名空間(namespace),它的做用是將用戶和數據庫的應用隔離到不一樣的數據庫或模式中,該模型在hive 0.6.0以後的版本支持,hive提供了create database dbname、use dbname以及drop database dbname這樣的語句。

2.表(table):hive的表邏輯上由存儲的數據和描述表格中的數據形式的相關元數據組成。表存儲的數據存放在分佈式文件系統裏,例如HDFS,元數據存儲在關係數據庫裏,當咱們建立一張hive的表,尚未爲表加載數據的時候,該表在分佈式文件系統,例如hdfs上就是一個文件夾(文件目錄)。Hive裏的表友兩種類型一種叫託管表,這種表的數據文件存儲在hive的數據倉庫裏,一種叫外部表,這種表的數據文件能夠存放在hive數據倉庫外部的分佈式文件系統上,也能夠放到hive數據倉庫裏(注意:hive的數據倉庫也就是hdfs上的一個目錄,這個目錄是hive數據文件存儲的默認路徑,它能夠在hive的配置文件裏進行配置,最終也會存放到元數據庫裏)。

下面是建立託管表的實例語句:

 

Create  table  tuoguan_tbl (flied string);
Load  data local  inpath ‘home/hadoop/test.txt’ into  table  tuoguan_tbl;

  

外部表建立的實例:

Create  external table  external_tbl (flied string)
     Location  ‘/home/hadoop/external_table’;
Load  data local  inpath ‘home/hadoop/test.txt’ into  table  external_tbl;

  

  你們看到了建立外部表時候table以前要加關鍵字external,同時還要用location命令指定文件存儲的路徑,若是不使用locaction數據文件也會放置到hive的數據倉庫裏。

  這兩種表在使用的區別主drop命令上,drop是hive刪除表的命令,託管表執行drop命令的時候,會刪除元數據和存儲的數據,而外部表執行drop命令時候只刪除元數據庫裏的數據,而不會刪除存儲的數據。另外我還要談談表的load命令,hive加載數據時候不會對元數據進行任何檢查,只是簡單的移動文件的位置,若是源文件格式不正確,也只有在作查詢操做時候才能發現,那個時候錯誤格式的字段會以NULL來顯示。

 3.分區(partition):hive裏分區的概念是根據「分區列」的值對錶的數據進行粗略劃分的機制,在hive存儲上就體如今表的主目錄(hive的表實際顯示就是一個文件夾)下的一個子目錄,這個文件夾的名字就是咱們定義的分區列的名字,沒有實際操做經驗的人可能會認爲分區列是表的某個字段,其實不是這樣,分區列不是表裏的某個字段,而是獨立的列,咱們根據這個列存儲表的裏的數據文件。使用分區是爲了加快數據分區的查詢速度而設計的,咱們在查詢某個具體分區列裏的數據時候不必進行全表掃描。下面我就舉一個分區使用的實例:

建立分區:

Create  table  logs(ts bigint ,line string)
Partitioned by  (dt string,country string);

  

 

加載數據:

Local  data local  inpath ‘/home/hadoop/par/file01.txt’ into  table  logs partition (dt=’2012-06-02’,country=’cn’);

  

 

在hive數據倉庫裏實際存儲的路徑以下所示:

/ user /hive/warehouse/logs/dt=2013-06-02/country=cn/file1.txt
/ user /hive/warehouse/logs/dt=2013-06-02/country=cn/file2.txt
/ user /hive/warehouse/logs/dt=2013-06-02/country=us/file3.txt
/ user /hive/warehouse/logs/dt=2013-06-02/country=us/file4.txt

  

 

咱們看到在表logs的目錄下有了兩層子目錄dt=2013-06-02和country=cn

查詢操做:

Select  ts,dt,line  from  logs where  country=’cn’,

  

這個時候咱們的查詢操做只會掃描file1.txt和file2.txt文件。

4.桶(bucket):上面的table和partition都是目錄級別的拆分數據,bucket則是對數據源數據文件自己來拆分數據。使用桶的表會將源數據文件按必定規律拆分紅多個文件,要使用bucket,咱們首先要打開hive對桶的控制,命令以下:

set  hive.enforce.bucketing = true

  

下面這段文字是我引用博客園裏風生水起的博文:

示例:
建臨時表student_tmp,並導入數據:
hive> desc  student_tmp;        
OK
id      int
age     int
name     string
stat_date       string
Time  taken: 0.106 seconds
hive> select  * from  student_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
Time  taken: 0.123 seconds
 
建student表:
hive> create  table  student(id INT , age INT , name  STRING)
        >partitioned by (stat_date STRING)
        >clustered by (id) sorted by (age) into  2 bucket
        >row format delimited fields terminated by  ',' ;
 
設置環境變量:
        > set  hive.enforce.bucketing = true ;
 
插入數據:
 
        > from  student_tmp
        > insert  overwrite table  student partition(stat_date= "20120802" )
        > select  id,age, name  where  stat_date= "20120801"  sort by  age;
 
查看文件目錄:
$ 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

  

  物理上,每一個桶就是表(或分區)目錄裏的一個文件,桶文件是按指定字段值進行hash,而後除以桶的個數例如上面例子2,最後去結果餘數,由於整數的hash值就是整數自己,上面例子裏,字段hash後的值仍是字段自己,因此2的餘數只有兩個0和1,因此咱們看到產生文件的後綴是*0_0和*1_0,文件裏存儲對應計算出來的元數據。

  Hive的桶,我我的認爲沒有特別的場景或者是特別的查詢,咱們能夠沒有必要使用,也就是不用開啓hive的桶的配置。由於桶運用的場景有限,一個是作map鏈接的運算,我在後面的文章裏會講到,一個就是取樣操做了,下面仍是引用風生水起博文裏的例子:

查看sampling數據:
hive> select  * from  student tablesample(bucket 1 out  of  2 on  id);                                                                              
Total MapReduce jobs = 1
Launching Job 1 out  of  1
.......
OK
4       18      mac     20120802
2       21      ljz     20120802
6       23      symbian 20120802
Time  taken: 20.608 seconds
 
tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUT  OF  y)
y必須是 table 總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如, table 總共分了64份,當y=32時,抽取 (64/32=)2個bucket的數據,當y=128時,抽取(64/128=)1/2個bucket的數據。x表示從哪一個bucket開始抽取。例 如, table 總bucket數爲32,tablesample(bucket 3 out  of  16),表示總共抽取(32/16=)2個bucket的數據,分別爲第3個bucket和第(3+16=)19個bucket的數據。

  

  好了,今天就寫到這裏了,明天要上班不能在加班寫文章了。這篇博文的內容並無寫完(hive存儲格式沒有寫),由於這個章節的知識很是重要是理解hive的關鍵,因此要講的細點,明天我爭取寫完hive存儲格式的文章,後天也就是本週二,我將爲咱們技術部門介紹hive的相關技術,寫博文算是個人預演了。

  最後我要講一下本身對大數據技術的見解,我以爲大數據技術是一個跨時代的技術,是互聯網技術的將來,也是雲計算的將來,它的深刻發展不只僅是數據處理上,也會改變整個互聯網技術的生態鏈,包括咱們使用的技術和開發語言,很慶幸親身經歷着整個偉大時代的變革,我也要展開雙臂迎接這個大時代的到來。

 

轉載:http://www.cnblogs.com/sharpxiajun/archive/2013/06/03/3114560.html

相關文章
相關標籤/搜索