抽取数据到impala数据量异常

最近,用kettle把DB2的数据抽取到impala上,发现数据量异常,数据错开等情况。

检查发现DB2源表里的数据某个字段中内容含有英文的逗号,而impala上建的表TERMINATED BY ','也用英文逗号分隔的,所以造成数据错乱;另外源表数据字段内容包含换行、回车符也会导致到impala数据分隔异常 数据错乱。
解决方案:针对分隔符,导致的 ;可以换一种分隔符 |,重新建表

CREATE TABLE DB_NAME.TB_NAME (
        ROW_ID DECIMAL(20,0),
        SLOGAN STRING,
        CREATED_TIME TIMESTAMP

)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
WITH SERDEPROPERTIES ('field.delim'='|', 'serialization.format'='|')
STORED AS TEXTFILE
LOCATION 'hdfs://IP:8020/user/hive/warehouse/XX.db/TB_NAME'

kettle 数据输出组件上的分隔符也对应调整
在这里插入图片描述
或者不需要重建表,获取数据时将字段中的英文逗号转换成中文的replace(SLOGAN,',',',')
如果源数据中存在换行回车符,可以trim(replace(replace(SLOGAN ,CHAR(13),''),CHAR(10),' '))
如果都有直接都替换再传到impala trim(replace(replace(replace(SLOGAN ,',',',') ,CHAR(13),''),CHAR(10),' '))

发现用kettle抽取DB2数据库的数据到impala上的表(TEXTFILE格式存储的表),源表中的字段例如ROW_ID是DECIMAL数值型的,impala上也是DECIMAL数值型的,如果不指定字段的长度和精度,hdfs文件里有数据内容,但是impala表select时row_id显示为null;指定了BigNumber类型的长度和精度后(hdfs文件中该字段值不足20位会在前面用0补齐位数)则能select出来
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
例如源表字段CREATED_TIME是TIMESTAMP格式的, impala上对应字段也是TIMESTAMP的,hdfs文件里的内容在时分秒后面有.000000000,则impala上查询数据时显示null;在这里插入图片描述在这里插入图片描述
在这里插入图片描述
源表日期数据要格式化转换下to_char(CREATED_TIME,'YYYY-MM-DD HH24:MI:SS') as CREATED_TIME再传即可
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以 源表数据字段类型、长度等要匹配上Impala表的字段数据类型,否则select不出来,显示null

备注:如果是mysql库里的TIMESTAMP的字段传到impala上(impala对应字段类型也是TIMESTAMP),日期数据转换下date_format(CREATED_TIME,'%Y-%m-%d %H:%i:%S') or date_format(CREATED_TIME,'%Y-%m-%d %T')

impala常用数据类型: 源自官方文档

数据类型详细说明
BIGINTRange:-9223372036854775808 - 9223372036854775807 ;用于建表或者sql中:CREATE TABLE t1(x BIGINT);SELECT CAST(1000 AS BIGINT)
DOUBLE存储4.94065645841246544e-324d 至 1.79769313486231570e+308 范围内的浮点值
DECIMAL存储十进制值 , Range:-10^38 +1 至 10^38 –1,最长的是DECIMAL(38, 0)
INT存储 -2147483648 至 2147483647范围内的 4字节 整数
SMALLINT存储 -32768至32767范围内的 2字节 整数
TINYINT存储 -128至127范围内的 1字节 整数
FLOAT存储 1.40129846432481707e-45 至 3.40282346638528860e+38 范围内的单精度浮点值
STRING存储 字符串值
VARCHAR存储可变长度字符,最大长度为65535,VARCHAR(max_length)
CHAR存储固定长度字符,最大长度为255,CHAR(length)
BOOLEAN只存储true或false值
TIMESTAMP存储时间格式的值,Range: 1400-01-01 to 9999-12-31,DATE_ADD (timestamp, INTERVAL interval time_unit)
ARRAYARRAY < type >,存储可变数量的有序元素,Complex Types (CDH 5.5 or higher only)
MAPMAP < primitive_type, type >,存储可变数量的键值对,Complex Types (CDH 5.5 or higher only)
STRUCTSTRUCT < name : type [COMMENT ‘comment_string’], … > ,表示单个项目的多个字段,Complex Types (CDH 5.5 or higher only)
REAL是DOUBLE类型的一个别名,REAL and DOUBLE interchangeably(可交换的)

www:
有张表的记录数据有创建时间和更新时间 TIMESTAMP格式,而且数据量较大;而记录在创建以后可能N天之后会进行更新(大于1次),每天要从DB2数据库更新数据到impala上;
创建TEXTFILE格式存储数据的临时表和PARQUET格式的正式表;每天根据临时表的数据 overwrite 正式表 insert overwrite table XX.XXXX partition(dt_month_id,dt_day_id) select * from XX.XXXX_tmp;
一开始我根据创建时间或者更新时间的年月日创建分区,后面直接获取最近几天更新记录数据,到最后 impala上总记录数据总是或多(根据更新时间创建分区)或少(根据创建时间创建),因为获取的数据量肯定比实际分区文件中的文件或多或少。
最终的解决办法是:截取创建时间的年月日创建分区cast(to_char(CREATED_TIME,'YYYYMMDD') as int) as dt_day_id,每天获取最近几天更新记录的创建时间最小值,获取大于等于最小创建时间的记录数据 更新那些天的文件: where CREATED_TIME >= (select substr(min(CREATED_TIME),1,10) || ' 00:00:00' from XX.TB_NAME where to_char(LAST_UPD_TIME,'YYYYMMDD') >= to_char(current date - 2 day,'YYYYMMDD') )

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值