FAQ系列 | 数据导入主键冲突问题

0、导读

用LOAD DATA导入数据却一直提示主键冲突问题解决案例。

1、问题描述

有位学生遇到数据导入时一直提示1022主键冲突问题,而导入的数据明明完全没有任何冲突,百思不得其解,请我帮忙协查。

下面是关于该问题现象描述:

1、表结构DDL

CREATE TABLE `wcp` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`txcode` char(4) NOT NULL,

`notice_from` enum(‘page’,’server’) ,

`message` varchar(600) NOT NULL ,

`signature` varchar(260) NOT NULL ,

`payment_no` char(30) NOT NULL ,

`notice_time` int(10) unsigned NOT NULL COMMENT ,

`dealt_ok` tinyint(1) NOT NULL DEFAULT ‘0’ COMMENT,

  PRIMARY KEY (`id`)

) ENGINE=ARCHIVE AUTO_INCREMENT=117 DEFAULT CHARSET=utf8;

欲导入的数据有116条,可以非常肯定的是,主键值都是顺序增长的,完全没有冲突,所以感觉非常奇怪。

2、原因分析

细心的同学,从上面我贴的表DDL或许能感觉出什么不对劲的味道(嗯,有点像狗狗嗅觉灵敏的意思,哈哈)

经我这么一提醒,再认真看一下,是不是真的发现了什么?嗯,很棒,答对了(从我女儿爱看的米奇妙妙屋里学到的语气词,嘿),该表的引擎是ARCHIVE,而不是我们常用的InnoDB或MyISAM,会不会和这个有关系呢?

ARCHIVE几乎没怎么被用过,非常冷门,它有什么特点呢。翻翻手册便知:

The ARCHIVE storage engine is used for storing large amounts of data without indexes in a very small footprint.

The ARCHIVE engine supports INSERT and SELECT, but not DELETE, REPLACE, or UPDATE. It does support ORDER BY operations, BLOB columns, and basically all but spatial data types (see Section 11.17.4.1, “MySQL Spatial Data Types”). The ARCHIVE engine uses row-level locking.

The ARCHIVE engine supports the AUTO_INCREMENT column attribute. The AUTO_INCREMENT column can have either a unique or nonunique index. Attempting to create an index on any other column results in an error. The ARCHIVE engine also supports the AUTO_INCREMENT table option in CREATE TABLE and ALTER TABLE statements to specify the initial sequence value for a new table or reset the sequence value for an existing table, respectively.

可以看到,ARCHIVE引擎和我们平时用的InnoDB、MyISAM区别还是很大的。它不支持DELETE、REPLACE、UPDATE等操作命令,只支持INSERT、SELECT、LOAD DATA等。ARCHIVE也支持自增列属性,但也必须是普通索引、唯一索引或主键索引(这个和其他引擎基本一致)。

接下来我们尝试解决数据导入主键冲突的问题。

3、问题解决

在这个例子中,想要最终能导入数据的话,有几个方法:

  1. 删除主键定义,或者删除主键的自增属性;
  2. 修改id列的主键索引为唯一索引或者普通索引;
  3. 调整表DDL定义时指定的AUTO_INCREMENT值为0或1;
  4. 修改表引擎为InnoDB或MyISAM;

第3个解决方案也是我自己几次反复测试才发现的,手册中也未提及,比较奇葩,这也是这次的案例令人最为不解的地方。

4、其他建议

我在很多场合强调过,InnoDB引擎已可适用95%以上的业务场景,完全没必要再使用其他引擎了,这次的奇葩案例也是一开始没注意到用ARCHIVE引擎而走了些弯路。

不听老叶言,吃亏在眼前,这话我看在理,嘿嘿~

 

关于MySQL的方方面面大家想了解什么,可以直接留言回复,我会从中选择一些热门话题进行分享。 同时希望大家多多转发,多一些阅读量是老叶继续努力分享的绝佳助力,谢谢大家 :)

最后打个广告,运维圈人士专属铁观音茶叶微店上线了,访问:http://yejinrong.com 直达

发表评论

电子邮件地址不会被公开。

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Time limit is exhausted. Please reload CAPTCHA.