HIve系統默認分隔符。通常下面2中情況我們需要需要用到分隔符
1,制作table的輸入文件,有時候我們需要輸入一些特殊的分隔符
2,把hive表格導出到本地時,系統默認的分隔符是^A,這個是特殊字符,直接cat或者vim是看不到的
分隔符在HIVE中的用途
分隔符 |
描述 |
\n |
對於文本文件來說,每行都是一條記錄,因此換行符可以分隔記錄 |
^A(Ctrl+A) |
用於分隔字段(列)。在CREATE TABLE語句中可以使用八進制編碼\001表示 |
^B(Ctrl+B) |
用於分隔ARRAY或者STRUCT中的元素,或用於MAP中鍵-值對之間的分隔。在CREATE TABLE語句中可以使用八進制編碼\002表示 |
^C(Ctrl+C) |
用於MAP中鍵和值之間的分隔。在CREATE TABLE語句中可以使用八進制編碼\003表示 |
Hive 中沒有定義專門的數據格式,數據格式可以由用戶指定,用戶定義數據格式需要指定三個屬性:列分隔符(通常為空格、”\t”、”\x001″)、行分隔符(”\n”)以及讀取文件數據的方法。
由於在加載數據的過程中,不需要從用戶數據格式到 Hive 定義的數據格式的轉換,因此,Hive 在加載的過程中不會對數據本身進行任何修改,而只是將數據內容復制或者移動到相應的 HDFS 目錄中。
sql:
row format delimited fields terminated by '\001' collection items terminated by '\002' map keys terminated by '\003' lines terminated by '\n' stored as textfile;
HIVE表中默認將NULL存為\N,可查看表的源文件(hadoop fs -cat或者hadoop fs -text),文件中存儲大量\N。
這樣造成浪費大量空間。而且用java、python直接進入路徑操作源數據時,解析也要注意。
另外,hive表的源文件中,默認列分隔符為\001(SOH),行分隔符為\n(目前只支持\n,別的不能用,所以定義時不需要顯示聲明)。元素間分隔符\002,map中key和value的分隔符為\003。
舉例,如源文件中一條記錄為:
可以看出存儲NULL的\N 浪費了大量空間。
但hive的NULL有時候是必須的:
1)hive中insert語句必須列數匹配,不支持不寫入,沒有值的列必須使用null占位。
2)hive表的數據文件中按分隔符區分各個列。空列會保存NULL(\N)來保留列位置。但外部表加載某些數據時如果列不夠,如表13列,文件數據只有2列,則在表查詢時表中的末尾剩余列無數據對應,自動顯示為NULL。
可以看出存儲NULL的\N 浪費了大量空間。
但hive的NULL有時候是必須的:
1)hive中insert語句必須列數匹配,不支持不寫入,沒有值的列必須使用null占位。
2)hive表的數據文件中按分隔符區分各個列。空列會保存NULL(\N)來保留列位置。但外部表加載某些數據時如果列不夠,如表13列,文件數據只有2列,則在表查詢時表中的末尾剩余列無數據對應,自動顯示為NULL。
所以,NULL轉化為空字符串,可以節省磁盤空間,實現方法有幾種
1)建表時直接指定(兩種方式)
a、用語句
實現,注意兩者必須一起使用,如
ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe’ with serdeproperties('serialization.null.format' = '')
--結合使用: CREATE TABLE hive_tb (id int,name STRING) PARTITIONED BY ( `day` string,`type` tinyint COMMENT '0 as bid, 1 as win, 2 as ck', `hour` tinyint) ROW FORMAT SERDE ‘org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe’ WITH SERDEPROPERTIES ( ‘field.delim’='/t’, ‘escape.delim’='//’, ‘serialization.null.format'='' ) STORED AS TEXTFILE;
b、或者通過ROW FORMAT DELIMITED NULL DEFINED AS '' 如
CREATE TABLE hive_tb (id int,name STRING) PARTITIONED BY ( `day` string,`type` tinyint COMMENT '0 as bid, 1 as win, 2 as ck', `hour` tinyint) ROW FORMAT DELIMITED NULL DEFINED AS '' STORED AS TEXTFILE;
2)修改已存在的表
alter table hive_tb set serdeproperties('serialization.null.format' = '');
節省空間的驗證結果如下:
hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=00/0* 1137 hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=01/0* 319753 ----------------------------------- hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=00/0* 885 hadoop fs -du /hivedata/warehouse/pmp.db/hive_tb/day=2016-05-14/type=1/hour=01/0* 249529