hive中dmp_device_info为映射到hbase中的dmp:device_info表,表结构如下:
CREATE EXTERNAL TABLE if not exists dmp_device_info( device_id_md5 string, device_type int, appids map<string,string>, tags map<string,string>, device_sources map<string,string>, update_time bigint ) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES('hbase.columns.mapping' = ':key,b:dt,a:,t:,s:,:timestamp') TBLPROPERTIES('hbase.table.name' = 'dmp:device_info');
dmp:device_info表结构:
列族 | 列名 |
---|---|
rowkey(行键) | device_id_md5(32) |
b | dt |
a | appid... 值为列名,1为列的值 |
t | tag... 值为列名,1为列的值 |
s | device_source...值为列名 |
appids,tags,device_sources都是映射了一个列族的数据,列族里面的列名为该字段的值。比如说在hive里面查询这三个字段的值:
select appids,tags,device_sources from dmp_device_info limit 1; 结果: {"366304":"1","372420":"1","388550":"1"} {"r60":"1"} {"103":"1"}
#假如总数为 100 有标签为 80 无标签的为 20 select count(1) from dmp_device_info where size(tags) = 0; 结果为:0 select size(tags),tags from dmp_device_info where size(tags) = 0; 结果为无数据。
#假如来源为101的无标签数据为10 select count(1) from dmp_device_info where size(tags) = 0 and device_sources['101'] = '1'; 结果:10 select tags,size(tags) from dmp_device_info where size(tags) = 0 and device_sources['101'] = '1' limit 1; 结果: {} 0
select count(1) from dmp_device_info; 结果:100 select count(1),sum(case when size(tags) > 0 then 1 else 0 end) from dmp_device_info; 结果:80 80 #一开始怀疑count和sum一起使用有问题,为什么都没加条件,count的值会改变???,心中一万个草泥马在奔腾。
经过几轮验证得出初步结论:
(这可以理解为hbase的BUG,反正草泥马一直没有停,这完全颠覆了对SQL的理解)
所以在统计或查询数据的时候,一定要加上一个每一行记录都有的一个字段。
比如:
#device_type在hbase表中条件记录都有值 select count(device_type) from dmp_device_info where size(tags) = 0; 结果:20