有没有办法将所有现有的表数据转换为 UTF8 排序规则?
Posted
技术标签:
【中文标题】有没有办法将所有现有的表数据转换为 UTF8 排序规则?【英文标题】:Is there a way to convert all existing table data to UTF8 collation? 【发布时间】:2013-03-07 20:42:29 【问题描述】:我正在协助将数据库从 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) 的非法混合”
【问题讨论】:
您确定字符集是导致 JOIN 查询失败的原因吗? - 你能举个例子吗,因为这不应该发生。 【参考方案1】:混合字符集不应导致查询失败,因为 MySQL 应根据需要在字符集之间进行转换。
但是,如 ALTER TABLE
Syntax 中所述:
要将表默认字符集和所有字符列(
CHAR
、VARCHAR
、TEXT
)更改为新字符集,请使用如下语句:ALTER TABLE <strong><em>tbl_name</em></strong> CONVERT TO CHARACTER SET <strong><em>charset_name</em></strong>;
对于数据类型为
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
,则CHAR
、VARCHAR
和TEXT
列将转换为其对应的二进制字符串类型(BINARY
、VARBINARY
、BLOB
)。这意味着这些列将不再具有字符集,并且后续的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
列进行转换时没有转换。
【讨论】:
以上是关于有没有办法将所有现有的表数据转换为 UTF8 排序规则?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法将 Redis 层设置为 OpsWorks 中现有的 Rails 应用程序?