2

我有一个最初使用 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,它就可以工作。我宁愿只修改东西而不是转储和重新创建,但如果没有人基于此提出任何其他建议或想法,我会求助于它。

4

2 回答 2

2

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

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,假设一切都可以转换为新的编码应该没问题。

于 2012-04-19T05:16:34.997 回答
1

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

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

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...东西可能不起作用(在我的情况下它没有)。

于 2012-04-20T03:45:12.587 回答