sqoop hive mysql null_sqoop导出hive数据到mysql避免空值

问题(1)

Sqoop导入导出Null存储一致性问题

Hive中的Null在底层是以“”\N“”来存储,而mysql中的Null在底层就是Null,为了保证数据两端的一致性,在导出数据时采用--input-null-string和--input-null-non-string两个参数。导入时采用--null-string和--null-non-string

问题(2)

Sqoop数据导出一致性问题

如sqoop在导出到mysql时,使用4个map任务,过程中有2个任务失败,此时mysql中存储了另两个map任务导入的数据,此时领导正好看到这个报表数据开发工程师发现之后,调试问题重新执行成功后,领导发现这次的数据跟上次不一样,这是不允许的。

使用--staing-table 参数,使用临时表,触发事物,成功后再导入目标表。

问题(3)

Sqoop底层运行的任务只有Map阶段,没有reduce阶段的任务。

问题(4)

在执行并行导入时,Sqoop需要一个可以划分工作负载的标准。Sqoop使用一个分割列来分割工作负载。默认情况下,Sqoop将标识表中的主键列(如果存在),并将其用作拆分列。从数据库中检索分割列的高值和低值,map任务操作整个范围的大小均匀的组件。例如,如果你有一个表的主键列id的最小值是0,最大值是1000,并且Sqoop直接使用4任务,Sqoop将运行四个进程,每个进程运行不同的任务在这个表上执行SQL语句SELECT * FROM sometable WHERE id >= lo AND id < hi,(lo,hi)设置为(0,250),(250,500),(500,750)和(750,1001)。

如果主键的实际值在其范围内不是均匀分布的,那么这可能导致任务不平衡。您应该使用参数--split-by显式地选择一个不同的列。例如,--split-by employee_id。Sqoop目前不能在多列索引上拆分。如果表没有索引列,或者有多列键,那么还必须手动选择就一个拆分列。

如果表没有定义主键,并且没有提供--split-by

,那么导入将失败,除非使用--num-mappers 1选项或--autoreset-to-one-mapper选项显式地将mapper数量设置为1。autoreset-to-one-mapper选项通常与import-all-tables工具一起使用,用于自动处理schema中没有主键的表。

sqoop导入导出问题

sqoop export --connect jdbc:mysql://ip:3306/eqpt_base_db?characterEncoding=utf8 --username root --password secret_password --table A_JQZ_T_GAS_GET_ORDER_NUM_INFO_S  --export-dir  /user/hive/warehouse/origin_ennenergy_energytrade.db/a_jqz_t_gas_get_order_num_info_s  --input-null-string '\\N' --input-null-non-string '\\N' --fields-terminated-by '\t'

为了避免空值时,没有数据,需要以下命令:

--input-null-string '\\N' --input-null-non-string '\\N' --fields-terminated-by '\t'

由sqoop导入失败发现的hive的空值问题

先说基础知识

hive中空值分两种

(1)NULL

hive中null实际在HDFS中默认存储为'\N',通过查询显示的是'NULL'。

这时如果查询为空值的字段可通过语句:aaa is null 或者 aaa ='\N' 实现。

此时可用hive中与null有关的函数,如nvl,coalesce,is null等判断是否为null是为true。

产生NULL值,一般都是由hive外链接引起的。

(2)''

'' 表示的是字段不为null且为空字符串,此时用 aaa is null 是无法查询这种值的,必须通过 aaa =='' 或者 length(aaa)=0 查询

产生''值,一般都是源数据为空。

之前项目中用到sqoop工具从HDFS中往数据库中导数据时,任务失败。不得已,用二分法导数据,去排查问题,看看是哪一条数据导致任务报错。最后排查到数据文件中有字段的值为空。但是奇怪的是,在hive sql里面已经加为null判断了。再看数据文件,发现其中的值不是通常的NULL,或者是\N,而是''。

所以得到原因,用判断null的nvl函数并不能排除''的情况,需要用IF(aaa == '','未知',aaa) AS aaa 来判断。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值