2

我正在协助将数据库从 MySQL 4 升级到 MySQL 5.5。我的客户端的应用服务器也从 JDK 5 升级到了 JDK 7。应用程序运行但是在执行数据库操作时抛出了很多异常。

我发现升级后的数据库在表排序和/或表列排序中混合使用了 Latin1 generic、Latin1 Swedish 和 UTF8 generic,因此大多数 JOIN 查询都失败了。

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

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

谢谢你。

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

“用于操作'='的排序规则(latin1_general_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)的非法混合”

4

1 回答 1

9

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

但是,如ALTER TABLE语法中所述:

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

ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;

对于具有数据类型VARCHAR或其中一种类型的列TEXTCONVERT 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列将转换为其对应的二进制字符串类型(BINARYVARBINARYBLOB)。这意味着这些列将不再具有字符集,并且后续CONVERT TO操作将不适用于它们。

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

 警告 

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

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

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

于 2013-03-19T09:00:26.290 回答