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

在尝试将Hive表数据导入到MySQL时遇到主键冲突问题,导致同步失败。解决方案包括:确保导入的联合主键字段在Hive和MySQL中都具有唯一值,注意字段类型和长度的匹配,以及在Hive中使用自增字段避免主键冲突。
摘要由CSDN通过智能技术生成

今天在将一个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,因此在导入数据时需保证不能出现重复值。

CREATE TABLE IF NOT EXISTS tmp_shujuxiong_20190116(

agent_id bigint(20) NOT NULL DEFAULT ‘0‘ comment ‘经纪人id‘,

agent_true_name varchar(1000) DEFAULT NULL comment ‘经纪人姓名‘,

longitude varchar(1000) DEFAULT NULL comment ‘用户所在经度‘,

latitude varchar(1000) DEFAULT NULL comment ‘用户所在纬度‘,

action_timestamp VARCHAR(200) NOT NULL comment ‘动作时间‘,

action_date VARCHAR(200) NOT NULL comment ‘动作日期‘,

event_name varchar(200) NOT NULL comment ‘事件名称‘,

estate_id bigint(20) NOT NULL comment ‘楼盘id‘,

estate_name varchar(1000) DEFAULT NULL comment ‘楼盘名称‘,

estate_developer_name varchar(1000) DEFAULT NULL comment ‘楼盘开发商名称‘,

estate_developer_brand_name varchar(1000) DEFAULT NULL comment ‘楼盘开发商品牌‘,

load_job_number varchar(1000) DEFAULT NULL comment ‘数据仓库调度工具oozie job单次运行id, 使用oozie EL function: ${wf:id()}‘,

load_job_name varchar(1000) DEFAULT NULL comment ‘数据仓库调度工具oozie_job名称: 使用oozie EL function: ${wf:name()}‘,

insert_timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment ‘数据仓库数据插入时间‘,

source_system_code INT(11) comment ‘数据仓库的源系统数据分类:1-二手房;2-新房;3-金融;4-租房‘,

dt varchar(8) NOT NULL comment ‘分区字段‘,

PRIMARY KEY (agent_id,estate_id,event_name,action_timestamp,dt),

KEY agent_id (agent_id)

) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT ‘XXX接口数据‘

;

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

(3)可以在hive表中使用一个自增字段起到类似主键的作用,以便于在hive和mysql间进行数据同步,确保数据同步时不发生主键冲突。

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

alter table tmp_table_name drop if exists partition (dt = ‘${dt}‘);

alter table tmp_table_name add if not exists partition (dt = ‘${dt}‘);

insert overwrite table tmp_table_name partition(dt = ‘${dt}‘)

select

row_number()over() as row_number -- 自增序号

, id

...

from ...

你可以使用Sqoop的export命令将Hive表中的数据导出到MySQL中。具体步骤如下: 1. 确保MySQL数据库已经创建好,并且具有与Hive表相同的表结构。 2. 在Sqoop的命令中,使用export参数指定需要导出的数据表,格式如下: ``` sqoop export --connect jdbc:mysql://mysql_host:port/mysql_database --username mysql_username --password mysql_password --table mysql_table --export-dir hive_table --input-fields-terminated-by '\t' --input-lines-terminated-by '\n' ``` 其中,`--connect`参数指定MySQL数据库的连接信息,`--username`和`--password`参数指定数据库的用户名和密码,`--table`参数指定需要导入MySQL表名,`--export-dir`参数指定需要导出的Hive表名,`--input-fields-terminated-by`参数指定Hive表中字段的分隔符,`--input-lines-terminated-by`参数指定Hive表中行的分隔符。 3. 如果Hive表中没有主键,则需要使用`--update-key`参数指定用于更新行的列名。例如,如果Hive表中有一个名为`id`的列,则可以使用以下命令: ``` sqoop export --connect jdbc:mysql://mysql_host:port/mysql_database --username mysql_username --password mysql_password --table mysql_table --export-dir hive_table --input-fields-terminated-by '\t' --input-lines-terminated-by '\n' --update-key id ``` 这将使用`id`列作为更新行的关键字。 4. 执行命令并等待导出完成。 注意:在执行Sqoop导出命令之前,需要确保Hive表中的数据已经是全量数据,否则可能会出现数据不一致的情况。如果需要覆盖MySQL中的数据,请确保备份MySQL中的数据,以防止数据丢失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值