2011-04-01 28 views
4

给定一个完整的表,如何将排序规则从utf8_bin更改为utf8_unicode_ce?由于“重复输入错误”,正常的“alter”查询不起作用。比如有两个条目MySQL:将排序规则从utf8_bin更改为utf8_unicode_ce

David Hussa 

David Hußa 

我知道他们是相同的。有没有一种方法可以告诉MySQL“合并”这些代码?我应该提到,这些条目的ID在其他表中用作参考,因此MySQL也必须遵守这些条目。或者,我必须这样做这个漫长而烦人的方式:手段合并每个重复手动,然后更改整理?

表看起来是这样的:

delimiter $$ 

CREATE TABLE `authors` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(100) COLLATE utf8_bin NOT NULL, 
    `count` int(11) NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name_UNIQUE` (`name`), 
    FULLTEXT KEY `name_FULLTEXT` (`name`) 
) ENGINE=MyISAM AUTO_INCREMENT=930710 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Stores all authors from dblp.xml.'$$ 

回答

5

您可以删除重复的条目:

DELETE a2 
FROM authors a1 
JOIN authors a2 
ON  a2.name COLLATE UTF8_GENERAL_CI = a1.name COLLATE UTF8_GENERAL_CI 
     AND a2.id < a1.id 

注意,这可能需要很长的时间,如果你的表是很大的。

这将是更好地做到这一点:

  • 删除该UNIQUE约束

  • 更改归类

  • 创建一个简单的,非唯一索引上name

  • 运行查询(不含COLLATE子句):

    DELETE a2 
    FROM authors a1 
    JOIN authors a2 
    ON  a2.name = a1.name 
         AND a2.id < a1.id 
    
  • 删除索引

  • 重新创建UNIQUE约束。

要更新引用表,删除条目之前运行此查询:

UPDATE child c 
JOIN (
     (
     SELECT name COLLATE utf8_unicode_ci AS name_ci, MAX(id) AS mid 
     FROM authors 
     GROUP BY 
       name_ci 
     ) pa 
     JOIN authors a 
     ON  a.name COLLATE utf8_unicode_ci = name_ci 
     ) 
ON  c.author = a.id 
SET  author = mid; 
上的所有引用表

+0

感谢您的重新安排。但问题仍然存在:如果某个名称的ID在另一个表中使用,并且该名称是重复的。这是由“其他”ID自动更新?我的意思是,如果“John Doe”id = 1,“JohnDoé”id = 2,那么第二个id会丢失,对吗? – Aufwind 2011-04-01 16:41:59

+0

@Aufwind:抱歉,最初不明白你的意思。不,它不会自动更新名称。你将不得不运行我现在写的查询。 – Quassnoi 2011-04-01 16:44:58

+0

非常感谢您的努力。它工作顺利。对于像我这样的其他noobies,我想添加这些注释:child是引用表的名称,c是其缩写,用于例如。 c。作者在第二行。花了我一些时间为自己弄清楚。 ^^ – Aufwind 2011-04-01 20:06:32