【发布时间】:2015-05-20 17:39:44
【问题描述】:
我需要将现有数据库从 Latin1 转换为 UTF8。看着here 我想我看到了我需要做的一切。但是,其他links 建议您必须实际导出数据,然后重新导入以保存数据。实际上需要哪个来防止任何数据丢失?如果没有办法真正防止任何数据丢失(丢失是对于不在两者之间映射的字符的不同编码),那么捕获所有这种情况的最佳方法是什么?我可以简单地做一个差异,还是有更快/更好的方法?
【问题讨论】:
我需要将现有数据库从 Latin1 转换为 UTF8。看着here 我想我看到了我需要做的一切。但是,其他links 建议您必须实际导出数据,然后重新导入以保存数据。实际上需要哪个来防止任何数据丢失?如果没有办法真正防止任何数据丢失(丢失是对于不在两者之间映射的字符的不同编码),那么捕获所有这种情况的最佳方法是什么?我可以简单地做一个差异,还是有更快/更好的方法?
【问题讨论】:
我相信所有 256 种 latin1 编码在 utf8 中都有映射。 (但肯定不是另一个方向。)因此,如果您有合适的代码,您不会丢失数据。我建议您在冒转换风险之前测试转换。
但首先,我们需要确保您进行了正确的转换。您有一个 latin1 列,其中包含 latin1 中的单字节重音字母?找一个带重音的单元格,SELECT LENGTH(col), CHAR_LENGTH(col) ...,如果长度相同,则为单字节编码,如latin1。
SELECT HEX(col) ... -- e-acute (é) 将是 latin1 中的 E9 或 utf8 中的 C3A9。这很重要——如果您有 E9,那么您需要将所有文本从 latin1 转换为 utf8 并更改列的声明。如果你已经有 C3A9,你已经有 utf8 伪装成 latin1;您需要更改声明而不修改字节。
第一种情况:ALTER TABLE tbl CONVERT TO CHARACTER SET utf8; -- 这会主动更改列中必要的字节。
第二种情况:alter table t modify c varbinary(...); alter table t modify c varchar(...) charset utf8;
关于该案例和其他案例的更多讨论: mysql.rjweb.org/doc.php/charcoll
【讨论】: