Hive中的一种假NULL

Hive中有种假NULL,它看起来和NULL一摸一样,但是实际却不是NULL

例如如下这个查询:

hive> desc ljn004;

OK

      string

Time taken: 0.237 seconds

 

hive> select a from ljn004;

OK

NULL

Time taken: 46.232 seconds

 

看上去好像ljn004a字段保存了一个 NULL

但是换一个查询会发现它和NULL并不一样:

hive> select a from ljn004 where a is null;

OK

Time taken: 62.56 seconds

 

来看一下实际存储的是什么:

hive> select * from ljn004;

OK

\N

Time taken: 1.232 seconds

 

hive> select a from ljn004 where a = '\\N';

OK

NULL

Time taken: 72.933 seconds

 

ljn004a字段实际存储的是一个'\N'a = '\\N'是因为Hive'\'是转义字符,需要对'\'进行一次转义,所以变成'\\N'

 

这种假NULL产生的原因实际上源于对表的错误操作。在Hive中,空值NULL在底层默认是用'\N'来存储的,看一个例子:

hive> create table ljn005 (col1 string);

OK

Time taken: 1.258 seconds

1 Rows loaded to ljn005

OK

Time taken: 63.727 seconds

 

hive> insert overwrite table ljn005 select NULL from dual;

 

然后看一下底层的数据存储:

$ hadoop fs -cat /group/hive/ljn005/attempt_201205041518_256192_m_000000_0

\N

 

可以看到底层数据将NULL存储成了'\N' 

这样的设计存在一个问题是如果实际想存储'\N',那么实际查询出来的也是NULL而不是'\N' 

Hive给出一种并非完美的解决方法就是可以自定义底层用什么字符来表示NULL

例如我想用字符'a'来表示NULL

hive> alter table ljn005 SET SERDEPROPERTIES('serialization.null.format' = 'a');

OK

Time taken: 0.175 seconds

 

hive> insert overwrite table ljn005 select NULL from dual;

1 Rows loaded to ljn005

OK

Time taken: 62.66 seconds

 

再看一下底层的存储:

$ hadoop fs -cat /group/hive/ljn005/attempt_201205041518_256764_m_000000_0

a

 

这时候底层的存储就变成了'a' ,今后插入到这张表中的'a'查询出来就变成了NULL而不是'a' 

 

其实上面说的这个假NULL出现的原因就是在默认情况下(即用'\N'表示NULL),插入了NULL值,然后又用SET SERDEPROPERTIES语句修改了存储NULL的字符串。这时候表的属性修改了,但是底层存储的文件并没有修改。而'\N'显示为NULLHive中又是一个特例,于是就出现了这个假NULL,在开发过程中一定要注意!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值