您的位置:首页 > 其它

对于有大量重复数据的表添加唯一索引

2014-11-24 14:45 393 查看

遇到如题的这么一个场景:需要在MySQL的一张innodb引擎的表(tableA)上添加一个唯一索引(idx_col1_u)。但是表中已经有大量重复数据,对于每个key(col1),有的重复2行,有的重复N行。

此时,做数据的手工清理,或者SQL处理无疑是非常耗时的。



1.Alterignoretablecometohelp

印象中MySQL有一个独有的alterignoreadduniqueindex的语法。

语法如下:


ALTER[ONLINE|OFFLINE][IGNORE]TABLE[code]tbl_name




行为类似于insertignore,即遇到冲突的unique数据则直接抛弃而不报错。对于加唯一索引的情况来说就是建一张空表,然后加上唯一索引,将老数据用insertignore语法插入到新表中,遇到冲突则抛弃数据。

文档中对于alterignore的注释:详见:http://dev.mysql.com/doc/refman/5.1/en/alter-table.html


IGNORE
isaMySQLextensiontostandardSQL.Itcontrolshow
ALTERTABLE
worksifthereareduplicatesonuniquekeysinthenewtableorifwarningsoccurwhenstrictmodeisenabled.If
IGNORE
isnotspecified,thecopyisabortedandrolledbackifduplicate-keyerrorsoccur.If
IGNORE
isspecified,onlythefirstrowisusedofrowswithduplicatesonauniquekey.Theotherconflictingrowsaredeleted.Incorrectvaluesaretruncatedtotheclosestmatchingacceptablevalue.



2.#1062-Duplicateentry

然而在执行了alterignoretabletableAadduniqueindexidx_col1_u(col1)后,还是报了以下错误:

#1062-Duplicateentry'111'forkey'col1'.

不是会自动丢弃重复数据么?世界观被颠覆了。查了下资料原来是alterignore的语法不支持innodb。

得知alterignore的实现完全取决于存储引擎的内部实现,而不是server端强制的,具体描述如下:


ForALTERTABLEwiththeIGNOREkeyword,IGNOREisnowpartofthe
informationprovidedtothestorageengine.Itisuptothestorage
enginewhethertousethiswhenchoosingbetweenthein-placeorcopy
algorithmforalteringthetable.ForInnoDBindexoperations,IGNORE
isnotusediftheindexisunique,sothecopyalgorithmisused


详见:http://bugs.mysql.com/bug.php?id=40344

3.解决方案

当然解决这个问题的tricky的方法还是有的,也比较直白粗暴。具体如下:


ALTERTABLEtableAENGINEMyISAM;
ALTERIGNORETABLEtableAADDUNIQUEINDEXidx_col1_u(col1)
ALTERTABLEtableENGINEInnoDB;




updatedin2013-09-26:

@jyzhou分享提到,可以不用改成MyISAM,而直接使用setold_alter_table=1;的方法。具体做法如下:

setold_alter_table=1;

ALTERIGNORETABLEtableAADDUNIQUEINDEXidx_col1_u(col1)

具体原理:http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_old_alter_table

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航