Hive數(shù)據(jù)類型和文件格式

Hive支持關(guān)系型數(shù)據(jù)庫的大多數(shù)基本數(shù)據(jù)類型,同時(shí)也支持關(guān)系型數(shù)據(jù)庫中很少出現(xiàn)的3種集合數(shù)據(jù)類型
為什么這么做?

  • 考慮因素一:數(shù)據(jù)類型是如何在文本中進(jìn)行表示
  • 考慮因素二:文本存儲(chǔ)中為了解決各種性能問題以及其他問題有哪些替代方案

基本數(shù)據(jù)類型

數(shù)據(jù)類型 長度 例子
TINYINT 1byte有符號(hào)整數(shù) 20
SMALINT 2byte有符號(hào)整數(shù) 20
INT 4byte有符號(hào)整數(shù) 20
BIGYINT 8byte有符號(hào)整數(shù) 20
BOOLEAN 布爾類型true或false TRUE
FLOAT 單精度浮點(diǎn) 3.14159
DOUBLE 雙精度浮點(diǎn) 3.14159
STRING 字符序列,可以指定字符集??梢允褂脝我?hào)或雙引號(hào) 'string',"string"
TIMESTAMP 整數(shù),浮點(diǎn)或者字符串 JDBC所兼容的時(shí)間格式
BINARY 字節(jié)數(shù)組 參考后面內(nèi)容

所有的這些數(shù)據(jù)類型都是對(duì)Java中的接口實(shí)現(xiàn),因此這些數(shù)據(jù)類型具體行為細(xì)節(jié)和Java中對(duì)應(yīng)的數(shù)據(jù)類型是完全一致的。
如果用戶在查詢中將一個(gè)float和double進(jìn)行比較,Hive會(huì)隱式地將類型轉(zhuǎn)換為兩個(gè)值中較大的類型,也就是把float轉(zhuǎn)為double。
用戶也可以顯示地將一種數(shù)據(jù)類型轉(zhuǎn)為其他一種數(shù)據(jù)類型,如:s = “1”,需要把s轉(zhuǎn)為int則可以用

cast ( s as int)

as 和 int 是關(guān)鍵字,大小寫都可以

集合數(shù)據(jù)類型

數(shù)據(jù)類型 描述 字面語法示例
STRUCT 和C語言中的stuct或者'對(duì)象'類似,都可以通過“點(diǎn)”符號(hào)訪問元素內(nèi)容。例如,如果某個(gè)列的元素類型是STRUCT{fisrt STRING,last STRING},那么第一個(gè)元素可以通過,字段名.first來引用 struct('John','Doe')
MAP MAP是一組鍵值對(duì)元組集合,使用數(shù)組表示法(例如['key'])可以訪問元素。例如,某個(gè)列的數(shù)據(jù)類型是MAP,其中鍵->值對(duì)是'fisrt' -> 'John'和'last' -> 'Doe',那么可以通過字段名['last']獲取最后一個(gè)元素 map('fisrt':'John','last':'Doe')
ARRAY 數(shù)組是一組具有相同類型和名稱的變量集合。這些變量稱為數(shù)組元素,每個(gè)數(shù)組元素都有一個(gè)編號(hào),編號(hào)從零開始。例如,數(shù)組值為['John','Doe'],那么第二個(gè)數(shù)組值可以用過數(shù)組名[1]進(jìn)行引用 Array('John','Doe')

大多數(shù)的關(guān)系型數(shù)據(jù)庫并不支持這些集合數(shù)據(jù)類型,因?yàn)槭褂盟鼈儠?huì)趨向于破壞標(biāo)準(zhǔn)格式。破壞標(biāo)準(zhǔn)帶來的問題是會(huì)增大數(shù)據(jù)冗余風(fēng)險(xiǎn),進(jìn)而導(dǎo)致不必要的磁盤空間,還有可能造成數(shù)據(jù)不一致,因?yàn)楫?dāng)數(shù)據(jù)發(fā)生改變時(shí)冗余的拷貝數(shù)據(jù)可能無法進(jìn)行相應(yīng)的同步

這里有一個(gè)用于演示如何使用這些數(shù)據(jù)類型的表結(jié)構(gòu)聲明語句,這是一張?zhí)摂M的人力資源應(yīng)用程序的員工表

CREATE TABLE employees(
       name STRING,
       salary FLOAT,
       subordinates ARRAY<STRING>,
       deductions MAP<STRING,FLOAT>,
       address STRUCT<street:STRING, city:STRING, state:STRING, zip:STRING> 
);

文本文件數(shù)據(jù)編碼

常見的文本文件的格式,有以逗號(hào)和制表符分隔的文本文件,也就是所謂的逗號(hào)分隔值(CSV)或制表符分隔值(TSV)。只要用戶需要,Hive是支持這些文件格式的。然而,這兩種格式的文件有一個(gè)共同的缺點(diǎn),那就是:

用戶需要對(duì)文本文件中那些不需要作為分隔符處理的逗號(hào)或者制表符格外小心

也因此,Hive默認(rèn)使用了幾個(gè)控制字符,這些字符很少出現(xiàn)在字段值中。Hive使用術(shù)語field來表示替換分隔符的字符。
Hive中默認(rèn)的記錄和字段分隔符如下表:

分隔符 描述
\n 對(duì)于文本來說,每行都是一條記錄,因此換行符可以分割記錄
^A(Ctrl+A) 用于分割字段(列)。在CREATE TABLE 語句中可以使用八進(jìn)制編碼\001表示
^B 用于分割A(yù)RRAY或者STRUCT中的元素,或用于MAP中鍵值對(duì)之間的分割。在CREATE TABLE語句中可以使用八進(jìn)制編碼\002表示
^C 用于MAP中鍵和值之間的分割。在CREATE TABLE語句中可以使用八進(jìn)制編碼\003表示

我們看一下employees表中的記錄,其中使用了^A等字符作為字段分割符:



用戶可以不使用這些默認(rèn)分隔符,而指定使用其他分隔符。下面這個(gè)表結(jié)構(gòu)和和之前那個(gè)表是一樣的,不過這里明確制定了分隔符:

CREATE TABLE employees(
       name STRING,
       salary FLOAT,
       subordinates ARRAY<STRING>,
       deductions MAP<STRING,FLOAT>,
       address STRUCT<street:STRING, city:STRING, state:STRING, zip:STRING> 
)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\001'
COLLECTION ITEMS TERMINATED BY '\002'
MAP KEYS TERMINATED BY '\003'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

ROW FORMAT DELIMITED這組關(guān)鍵字必須要寫在其他字句(除了 STORED AS ...)之前

讀時(shí)模式

傳統(tǒng)的數(shù)據(jù)庫是寫時(shí)模式(schema on write),即數(shù)據(jù)在寫入數(shù)據(jù)庫時(shí)對(duì)模式進(jìn)行檢查。
Hive對(duì)底層存儲(chǔ)并沒有這樣的控制。Hive不會(huì)在數(shù)據(jù)加載時(shí)進(jìn)行驗(yàn)證,而是在查詢時(shí)進(jìn)行,也就是讀時(shí)模式。
那么如果模式和文件內(nèi)容不匹配將會(huì)怎么樣呢?

Hive對(duì)此做的非常好,因?yàn)槠淇梢宰x取這些數(shù)據(jù)。如果每行記錄匯總字段個(gè)數(shù)少于對(duì)應(yīng)模式中定義的字段個(gè)數(shù)的話,那么用戶將會(huì)看到查詢結(jié)果中有很多null值。如果某些字段是數(shù)值型,但Hive在讀取時(shí)發(fā)現(xiàn)存在非數(shù)值型的字符串值的話,那么對(duì)于那些字段將會(huì)返回null值。除此之外的情況,Hive都極力嘗試盡可能將各種錯(cuò)誤恢復(fù)過來

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容