1. 程式人生 > >hive中的NULL(hive空值處理)

hive中的NULL(hive空值處理)

HIVE表中預設將NULL存為\N,可查看錶的原始檔(hadoop fs -cat或者hadoop fs -text),檔案中儲存大量\N,  
這樣造成浪費大量空間。而且用java、python直接進入路徑操作源資料時,解析也要注意。

另外,hive表的原始檔中,預設列分隔符為\001(SOH),行分隔符為\n(目前只支援\n,別的不能用,所以定義時不需要顯示宣告)。元素間分隔符\002,map中key和value的分隔符為\003。

舉例,如原始檔中一條記錄為:
10000042SOH77SOH435SOH16SOH22SOH1156120000SOH\NSOH\NSOH\NSOH\NSOH\NSOH\NSOH
\NSOHyoukuSOH85133.0SOH111
可以看出儲存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