用LOAD DATA导入数据却一直提示主键冲突问题解决案例。
有位学生遇到数据导入时一直提示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,
) ENGINE=ARCHIVE AUTO_INCREMENT=117 DEFAULT CHARSET=utf8;
欲导入的数据有116条,可以非常肯定的是,主键值都是顺序增长的,完全没有冲突,所以感觉非常奇怪。
细心的同学,从上面我贴的表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也支持自增列属性,但也必须是普通索引、唯一索引或主键索引(这个和其他引擎基本一致)。
接下来我们尝试解决数据导入主键冲突的问题。
在这个例子中,想要最终能导入数据的话,有几个方法:
删除主键定义,或者删除主键的自增属性;
修改id列的主键索引为唯一索引或者普通索引;
调整表DDL定义时指定的AUTO_INCREMENT值为0或1;
修改表引擎为InnoDB或MyISAM;
第3个解决方案也是我自己几次反复测试才发现的,手册中也未提及,比较奇葩,这也是这次的案例令人最为不解的地方。
我在很多场合强调过,InnoDB引擎已可适用95%以上的业务场景,完全没必要再使用其他引擎了,这次的奇葩案例也是一开始没注意到用ARCHIVE引擎而走了些弯路。
不听老叶言,吃亏在眼前,这话我看在理,嘿嘿~