sqoop从hive导入数据到mysql时出现主键冲突

今天在将一个hive数仓表导出到mysql数据库时出现进度条一直维持在95%一段时间后提示失败的情况,搞了好久才解决。使用的环境是HUE中的Oozie的workflow任何调用sqoop命令,该死的oozie的日志和异常提示功能太辣鸡了,最后发现是重复数据导致数据进入mysql表时出现主键冲突进而导致数据同步失败。

(1)众所周知hive表是没有主键与索引的,但是mysql的表一般在创建时就会指定主键,所以在把hive表中的数据导入mysql表的时候通常会使用原hive表中的多个字段构成联合主键,这几个主键字段的值必须能唯一地标识表中的每一条记录,也即导入数据的这几个字段的联合值不能出现重复值。

比如下面这张mysql表中主键由5个字段构成agent_id,estate_id,event_name,action_timestamp,dt,因此在导入数据时需保证不能出现重复值。

1CREATE TABLE IF NOT EXISTS tmp_shujuxiong_20190116( 2agent_id bigint(20) NOT NULL DEFAULT '0' comment '经纪人id', 3agent_true_name varchar(1000) DEFAULT NULL comment '经纪人姓名', 4longitude varchar(1000) DEFAULT NULL comment '用户所在经度', 5latitude varchar(1000) DEFAULT NULL comment '用户所在纬度', 6action_timestamp VARCHAR(200) NOT NULL comment '动作时间', 7action_date VARCHAR(200) NOT NULL comment '动作日期', 8event_name varchar(200) NOT NULL comment '事件名称', 9estate_id bigint(20) NOT NULL comment '楼盘id', 10estate_name varchar(1000) DEFAULT NULL comment '楼盘名称', 11estate_developer_name varchar(1000) DEFAULT NULL comment '楼盘开发商名称', 12estate_developer_brand_name varchar(1000) DEFAULT NULL comment '楼盘开发商品牌', 13 14load_job_number varchar(1000) DEFAULT NULL comment '数据仓库调度工具oozie job单次运行id, 使用oozie EL function: ${wf:id()}', 15load_job_name varchar(1000) DEFAULT NULL comment '数据仓库调度工具oozie_job名称: 使用oozie EL function: ${wf:name()}', 16insert_timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '数据仓库数据插入时间', 17source_system_code INT(11) comment '数据仓库的源系统数据分类:1-二手房;2-新房;3-金融;4-租房', 18dt varchar(8) NOT NULL comment '分区字段', 19PRIMARY KEY (agent_id,estate_id,event_name,action_timestamp,dt), 20KEY agent_id (agent_id) 21) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT 'XXX接口数据' 22;

(2)另一个需要注意的问题的是字段类型与字段长度,hive的数据类型与mysql的数据不完全相同,因此mysql中创建表的时候需要特别注意字段的类型与长度。

(3)可以在hive表中使用一个自增字段起到类似主键的作用,以便于在hive和mysql间进行数据同步,确保数据同步时不发生主键冲突。这个可以参考本人另一篇博文https://www.cnblogs.com/shujuxiong/p/10978410.html

 如下面这段HQL脚本中可以使用自增序号字段起到主键的作用,在其他字段组合不能保证数据唯一性的时候

1alter table tmp_table_name drop if exists partition (dt = '${dt}'); 2alter table tmp_table_name add if not exists partition (dt = '${dt}'); 3 4insert overwrite table tmp_table_name partition(dt = '${dt}') 5select 6 row_number()over() as row_number -- 自增序号 7 , id 8 ... 9from ...
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''

Twitter的分布式自增ID算法snowflake (Java版)

概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移