2011-04-01 119 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