Hive支持RDBMS中的大多數數據類型,同時也支持RDBMS中很少支持的3中集合數據類型。
一、基本數據類型
1. Integers 整數型
TINYINT—1 byte integer
SMALLINT—2 byte integer
INT—4 byte integer
BIGINT—8 byte integer
以上這些都是有符號的整型。
2. Boolean type 布爾型
BOOLEAN—TRUE/FALSE
3. Floating point numbers 浮點型
FLOAT—single precision 單精度浮點
DOUBLE—Double precision 雙精度浮點
4. Fixed point numbers 定點型
DECIMAL—a fixed point value of user defined scale and precision
5. String types 字符序列
STRING—sequence of characters in a specified character set
VARCHAR—sequence of characters in a specified character set with a maximum length
CHAR—sequence of characters in a specified character set with a defined length
7. Date and time types 時間類型
TIMESTAMP—a specific point in time, up to nanosecond precision
DATE—a date
8. Binary types 字節數組
BINARY—a sequence of bytes
為什么有的字符類型很特殊呢? 這是因為所有這些數據類型都是對Java中的接口的實現,比如string類型實現的和Java中的string,float中也是對Java中的float。
但是其他RDBMS通常也會提供限制最大長度的字符數組,而在Hive中卻不會支持。因為處于性能優化的考慮,這些定長的記錄容易進行索引、掃描等。而在Hive強調優化磁盤讀寫的性能對限制列的長度相對來說不是很重要。
在Hive0.8.0以后的timestamp、binary數據類型數據類型;timestamp指可以為整數,也就是距離Unix新紀元的秒數;也可以是浮點數,距離到納秒(小數點后保留9位),也可以是字符串,即JDBC所約定的的字符串格式,比如:yyyy-mm-dd hh24:mi:ss.fffffffff。
binary類型和其他的RDBMS數據庫中的varbinary很類似。不過它并不和blob數據類型并不同。因為binary列存儲在記錄中,而blob不同。
當用戶查詢用到不同的浮點列對比是,比如將float和double列進行對比或一個整數列和另一種整數列對比時,Hive會怎么樣處理呢?遇到這種情況,Hive會隱式的將把數據類型轉換為兩個數據類型較大的那個處理,也就是將float轉換成double。
二、集合數據類型
Hive 中的列支持使用 struct、map、array 集合數據類型,如下:
STRUCT列類型為struct{first STRING,last STRING} ? ? 如: struct('john','Doe')
MAP是一組鍵值對集合 字段名[last]獲取值 ? ?如:map('first','Join','last','Doe')
ARRAY是具有相關同類型和名稱的變量的集合['John','Doe'] ? ?如:Array(['John','Doe']?)
大多數的關系型數據庫并不支持這些集合數據類型,這有破壞標準數據格式的危險。通常在RDBMS中的處理方式大概用主外鍵關聯。我們知道主外鍵關聯的話在進行TB級以上的數據處理時會造成性能的極大消耗。但在大數據庫架構中,這種設計卻有助于提高數據吞吐量。
例如:
CREATE TABLE employees(
name STRING,
salary float,
subordinates array<string>,
deductions map<string,float>,
address struct<street:string,city:string,state:string,zip:int>?
)
name --雇員名,salary --雇員薪水,subordinates --下屬員工,deductions --五險一金,個稅等,address --雇員的住址
很明顯,一個雇員表詳細信心存儲在一張表中,在RDBMS中則可能存在某個字段的信息存儲在另外一張表,通過主外鍵或查詢條件進行連接后獲取結果。這里可以通過一些集合數據類型進行處理了就。
三、文本文件的數據編碼
我們知道,一個文本文件如果需要進行數據處理,就需要對其中的格式進行定義,我們最熟悉的應該是以逗號或制表符分隔的文本格式CSV、TSV,當然在Hive中,這些文本格式都是被支持的。
那么Hive中還會支持其他什么控制字符的文本格式呢?
\n ? ? ? ? ? ? ? ? ? ? ? 換行符是可以支持的,因為每一行都可以被認為是一條記錄
^A(Ctrl+A) ? ? 分隔字段,在 CREATE TABLE 語句中可以使用八進制編碼(\001)表示
^B ? ? ? ? ? ? ? ? ? ? ?分隔 ARRAY 、MAP或者 STRUCT 中的元素,鍵值對之間的分隔,使用八進制編碼(\002)表示
^C ? ? ? ? ? ? ? ? ? ? ?用于 MAP 中鍵和值之間的分隔,使用八進制編碼(\003)表示
比如將一個特定格式的文件插入到employees庫中,文件打開后數據格式顯示如下:
Shkodran Mustafi^A5000^ALaurent Koscielny^BRobert Holding^BHector Bellerin^AFederal^C.2^BState Taxes^C.05^BInsurance^C.1^A 1 Michigan Ave.^BChicago^BIL^B60600
我們可以針對此文件進行分解,讓我們對格式更加清晰一些:
1、Shkodran Mustafi 對應 'name'字段,字段間用^A分割,所有在和salary字段之間的地方使用了^A。
2、5000對應’salary'字段,同樣的用^A 隔斷下一個字段。
3、Laurent Koscielny^BRobert Holding^BHector Bellerin 對應'subordinates'字段,針對array元素內的分割使用^B。
4、Federal^C.2^BState Taxes^C.05^BInsurance^C.1 對應‘deductions’字段,map元素內的分割使用^C。
5、1 Michigan Ave.^BChicago^BIL^B60600 對應‘address’字段,struct元素內的分割使用^B。
拆分后,是不是很清楚了呢?
也可以不使用這些默認的分隔符,而指定其他的分隔符,例如之前的表可以:
CREATE TABLE employees(
name STRING,
salary FLOAT,
subordinates ARRAY(STRING),
deductions MAP(STRING,FLOAT),
address ? ?STRUCT
)
ROW FORMAT DELIMITED--必須寫在下面的子句之前(stored as 除外)
FILEDS TERMINATED BY '\001'--Hive 將使用 ^A 做為列分隔符
COLLECTION ITEMS TERMINATED BY '\002'--表明Hive 將使用 ^B 做為集合元素間分隔符
MAP KEYS TERMINATED BY '\003'--表明Hive 將使用 ^C 做為 MAP 的鍵值之間的分隔符
LINES TERMINATED BY '\n'--下面這兩句表明不需要?ROW FORMAT DELIMITED 做關鍵字
STORED AS TEXTFILE;--此句很少被用到
另外,定義一個表是按照逗號來分隔的數據表可以這么來:
create table test_2(fistr float, second float, third float) row format delimited fileds terminated by ',';
雖然用戶可以自定義一些分隔符,但是大多數子句還是使用默認分隔符的,只需要指定明確替換的分隔符即可。所以Hive可以容易的使用由很多ETL工具或其他程序產生的文件。
四、讀時模式
當用戶向數據庫進行數據寫入時,可以采用外部裝載、update語句,或者查詢寫入。傳統數據庫時寫時模式,什么意思呢,即只在數據寫入時對模式進行檢查。
Hive對底層存儲沒有一些控制手段,對于要查詢的數據,有很多方式可以進行創建、修改或進行破壞。因此,hive不會在數據加載時才對模式進行驗證,而在查詢時就對其模式進行驗證,這是讀時模式。
如果模式和文件內容并不匹配,每行記錄中的字段個數少于對應的模式中定義的字段個數的話,那么用戶將會看到查詢結果中有很多 null 值 ;如果某些字段是數值型的,但Hive 在讀取的時候發現存在非數值型的字符串值的話,將返回 null 值。