【问题标题】:MySQL Character EncodingsMySQL 字符编码
【发布时间】:2012-04-19 05:11:16
【问题描述】:

我有一个最初使用 latin1 编码和 latin1_swedish_ci 排序规则创建的大型数据库。

我做了很多更改,现在我使用的是 Doctrine2,它在查询之前使用 SET NAMES UTF8。我之前使用的是 Yii 框架,该框架也设置为使用 UTF-8。基本上我一开始就忽略了所有这些,但据我了解,我一直在将 UTF-8 数据写入数据库,尽管它应该都是 latin1。

我想将我的数据库转换为 utf-8,但不知道如何安全地执行此操作并确保我不会丢失数据。

两个问题:

  1. 有没有办法确保我已正确完成此操作?我有 2 GB 的数据,所以我不能只扫描它来测试,但是我可以寻找某些字符来确定数据库是否已经使用 UTF-8?

  2. 转换所有内容的正确方法是什么?我见过有人说我必须 mysqldump 并重新导入(带有某些标志,http://blog.makezine.com/2007/05/08/mysql-database-migration-latin/http://docs.moodle.org/22/en/Converting_your_MySQL_database_to_UTF8)。其他人说你可以ALTER TABLE... 每列(http://www.bothernomore.com/2008/12/16/character-encoding-hell/)。我认为SET utf8 之类的命令是ALTER TABLE 的一部分,但我不知道这是否有效。

编辑:

我已转储数据并发现了几个重音字符。这是否表明数据本身是 UTF-8?如果是这样,我认为此处的说明适用,因为我可以“转换”为 blob 并安全返回 http://codex.wordpress.org/Converting_Database_Character_Sets

再次编辑:

在完成我在上一个链接中阅读的内容后,我发现比较数据后,我丢失了第一个非 ascii(?) 之后的所有字符。所以我用单引号设置了标题,新的数据库有那个字符和它之后的所有字符。例如,这是我正在运行的代码:

ALTER TABLE articles CHANGE title title VARBINARY(255) NOT NULL;
ALTER TABLE articles CHANGE title title VARCHAR(255) CHARACTER SET utf8 NOT NULL;

不知何故导致我丢失了数据。

但是,如果我转储,将每个表的字符集从 latin1 更改为 utf8,它就可以工作。我宁愿只修改东西而不是转储和重新创建,但如果没有人基于此提出任何其他建议或想法,我会求助于它。

【问题讨论】:

  • 我有类似的问题。我使用 HeidiSQL 的批量维护功能。

标签: mysql utf-8 character-encoding


【解决方案1】:

要检查事情,您可以执行以下操作:

SELECT t1.*
FROM table_1 t1 
JOIN table_1 t2 on t1.guid = t2.guid AND
t1.field_1 <> t2.field_1 COLLATE UTF-8

基本上,即时更改列的排序规则,看看是否会出现任何问题。

您绝对不需要重新导入所有内容,ALTER TABLE 到新的编码应该没问题,假设一切都可以转换。

【讨论】:

  • 我必须alter table 并单独更改所有字符串列吗?这似乎是我正在阅读的内容
  • 另外,试过了:mysql&gt; SELECT t1.* FROM articles t1 JOIN articles t2 ON t1.id = t2.id AND t1.title &lt;&gt; t2.title COLLA TE utf8_general_ci LIMIT 10; ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'
  • 如果你正在做你的整个 db.. 可能只使用 sqldump 代替,或者以编程方式循环每一列。您是否尝试过使用嵌套的COLLATE?喜欢t1.title &lt;&gt; (t2.title COLLATE utf8_general_ci) COLLATE latin1
  • 还是一个错误。 mysql&gt; SELECT t1.* FROM articles t1 JOIN articles t2 ON t1.id = t2.id AND t1.title &lt;&gt; (t2.title COLL ATE utf8_general_ci) collate latin1 LIMIT 10; ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1' 我正在考虑遍历每一列以“转换”到 blob 并返回 UTF-8。我在 Amazon RDS 上,不想在 I/O 操作上花费更多的钱来转储和导入。
【解决方案2】:

我让它与转储一起工作并重新导入。我主要遵循本指南:http://en.gentoo-wiki.com/wiki/Convert_latin1_to_UTF-8_in_MySQL

如果有其他人遇到我的情况(您将 UTF-8 数据存储在您一直通过调用 SET NAMES utf8 访问的 latin1 数据库中,那么您可以尝试以下方法(我对上述来源的修改)。

mysqldump -h example.org --user=foo -p -c --insert-ignore --skip-set-charset -r dump.sql dbname

仔细检查它是 UTF-8(我的是)

file dump.sql

在转储上进行转换

perl -pi -w -e 's/CHARSET=latin1/CHARSET=utf8/g;' dump.sql

创建一个新的数据库(我没有删除旧的以防万一)

mysql --user=foo -p --execute="CREATE DATABASE dbnameutf8 CHARACTER SET utf8 COLLATE utf8_general_ci;"

导入

mysql --user=foo -p --default-character-set=utf8 dbnameutf8 < dump.sql

希望可以帮助别人。请记住,ALTER TABLE... 的东西可能不起作用(在我的情况下它不起作用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2013-04-26
    • 1970-01-01
    • 2014-12-21
    • 2013-09-06
    相关资源
    最近更新 更多