有没有办法将所有现有的表数据转换为UTF8整理?

时间:2013-03-19 08:54:28

标签: mysql

我正在协助从MySQL 4到MySQL 5.5的数据库升级。我的客户端的应用程序服务器也已从JDK 5升级到JDK 7.但是,在执行数据库操作时,应用程序运行会引发许多异常。

我发现升级后的数据库在表排序规则和/或表列排序规则中使用了Latin1泛型,Latin1瑞典语和UTF8泛型的混合,因此大多数JOIN查询都失败了。

有数百个表和数千个表字段,手动转换所有表格将非常困难。

是否有更方便的方法将所有数据表和所有列转换为相同的排序规则?

谢谢。

编辑:显示JOIN查询失败的SQLException消息示例:

“非法混合排序(latin1_general_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)进行操作'='”

1 个答案:

答案 0 :(得分:7)

混合使用字符集不应导致查询失败,因为MySQL应根据需要在字符集之间进行转换。

但是,如ALTER TABLE Syntax所述:

  

要将表默认字符集和所有字符列(CHARVARCHARTEXT)更改为新字符集,请使用如下语句:

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
     

对于数据类型为VARCHAR或其中一种TEXT类型的列,CONVERT TO CHARACTER SET会根据需要更改数据类型,以确保新列的长度足以支持存储与原始列一样多的字符。例如,TEXT列有两个长度字节,用于存储列中值的字节长度,最大值为65,535。对于latin1 TEXT列,每个字符都需要一个字节,因此该列最多可以存储65,535个字符。如果列转换为utf8,则每个字符最多可能需要三个字节,最大可能长度为3×65,535 = 196,605字节。该长度不适合TEXT列的长度字节,因此MySQL将数据类型转换为MEDIUMTEXT,这是长度字节可以记录值196,605的最小字符串类型。同样,VARCHAR列可能会转换为MEDIUMTEXT

     

为避免更改上述类型的数据类型,请勿使用CONVERT TO CHARACTER SET。而是使用MODIFY更改单个列。例如:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;
     

如果您指定CONVERT TO CHARACTER SET binary,则CHARVARCHARTEXT列会转换为相应的二进制字符串类型(BINARY,{{3 },VARBINARY)。这意味着列不再具有字符集,后续CONVERT TO操作将不适用于它们。

     

如果 charset_name DEFAULT,则使用数据库字符集。

     
    

警告

         

CONVERT TO操作会在字符集之间转换列值。如果您在一个字符集中有一列(如latin1),那么你想要的是什么,但存储的值实际上使用了一些其他不兼容的字符集(如utf8) 。在这种情况下,您必须为每个此类列执行以下操作:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
         

这样做的原因是当您转换为BLOB列或来自BLOB列时没有转化。