1. 程式人生 > >[Hive]Hive使用指南七 空值與NULL

[Hive]Hive使用指南七 空值與NULL

1. NULL(null)值

建立一個臨時表tmp_null_empty_test,並插入一些NULL資料:

CREATE  TABLE IF NOT EXISTS tmp_null_empty_test(  uid string)ROW FORMAT DELIMITEDFIELDS TERMINATED BY '\t'LINES TERMINATED BY '\n'STORED AS TEXTFILE;

INSERT OVERWRITE TABLE tmp_null_empty_test select NULL from test WHERE dt = '20171016';

我們看一下從Hive中取出來的資料:

hive> select * from tmp_null_empty_test;
OK
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
NULL
...

我們再看一下這張表在HDFS上究竟是如何儲存的?

hadoop fs -text /user/hive/warehouse/test.db/tmp_null_empty_test/* | less
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
\N
...

發現Hive將NULL值儲存為'\N'。

Hive在底層資料中如何儲存和標識NULL,是由serialization.null.format

引數控制的,預設為serialization.null.format'='\\N。我們可以更改這一引數使之NULL值儲存為其他形式,例如下面我們更改為"null":

ALTER TABLE tmp_null_empty_test SET SERDEPROPERTIES('serialization.null.format' = 'null');

我們刪除資料重新倒入一遍資料:

hadoop fs -text /user/hive/warehouse/test.db/tmp_null_empty_test/* |less
null
null
null
null
null
null
null
null
null
...

這樣的設計存在一個問題是如果實際想儲存'\N',那麼實際查詢出來的也是NULL而不是'\N' 。所以如果真的想儲存'\N'時,可以更改配置引數為其他格式即可。

那我們在Hive中如何查詢等於'NULL'的那些值呢?可以使用如下命令查詢:

hive> select * from tmp_null_empty_test where uid is null;
OK
NULL
NULL
NULL
NULL
NULL
...

2. 空字串

我們再看一下儲存空字串的情況,刪除之前的資料,重新匯入一些空字串:

INSERT OVERWRITE TABLE tmp_null_empty_test select "" from test WHERE dt = '20171016';

我們看一下從Hive中取出來的資料:

hive> select * from tmp_null_empty_test;
OK

...

Time taken: 0.047 seconds, Fetched: 36 row(s)

我們再看一下在HDFS上究竟是如何儲存的?

hadoop fs -text /user/hive/warehouse/test.db/tmp_null_empty_test/* |less

...

對於空字串我們使用如下命令查詢:

hive> select count(*) from tmp_null_empty_test where uid = "";
OK
36

但是不能使用is null來判斷:

hive> select count(*) from tmp_null_empty_test where uid is null;
OK
0

3. 資料型別與NULL

INT與STRING的儲存,NULL預設的儲存都是'\N'。如果資料型別為String的資料為"",儲存才是""。如果往Int型別的欄位插入""資料,儲存為'\N'。 查詢的時候,對於Int型別資料可以使用IS NULL來判斷NULL值;對於String資料型別的資料採用IS NULL來查詢NULL值,採用=""來查詢空字串。

我們遇到的一個Case,在查詢String資料型別uid缺失的資料時,我們不得不使用IS NULL=""兩個判斷條件進行過濾,我們其實想遵循SQL規範使用IS NULL一個判斷條件判斷即可,但是在Hive中與傳統的資料庫又不一樣,在於NULL的解讀不同。如果想延續傳統資料庫中對於空值為NULL,可以通過alter語句來修改hive表的資訊,保證解析時是按照空值來解析NULL值:

ALTER TABLE tmp_null_empty_test SET SERDEPROPERTIES('serialization.null.format' = '');

Example:

hive> INSERT OVERWRITE TABLE tmp_null_empty_test select "" from test WHERE dt = '20171016';
hive> select count(*) from tmp_null_empty_test where uid is null;
OK
36

備註:

Hive版本為2.1.1