【问题标题】:When I write special latin1 characters to an utf-8 encoded mysql table, is that data lost?当我将特殊的 latin1 字符写入 utf-8 编码的 mysql 表时,该数据会丢失吗?
【发布时间】:2012-10-26 12:06:41
【问题描述】:

当我写特殊的 latin1 字符时,例如

á, é ã, ê

到一个 utf-8 编码的 mysql 表,数据会丢失吗?

该表的字符集是 utf-8。

有什么方法可以取回 latin1 编码的行,以便我可以转换为 utf-8 并回写(这次以正确的方式)?

更新

我想我对“数据”的含义不是很具体。数据是指特殊字符,而不是行。

选择时,我仍然得到行和字段,但带有“?”而不是特殊的 latin1 字符。有可能恢复那些'?并转换为正确的 utf8 格式?

【问题讨论】:

    标签: mysql


    【解决方案1】:

    如果整个数据库(或整个表)受到影响,可以先用SET NAMES Latin1验证是拉丁1-as-UTF8字符集问题:

    mysql> select txt from tbl;
    +-----------+
    | txt       |
    +-----------+
    | Québec   |
    | Québec   |
    +-----------+
    2 rows in set (0.00 sec)
    
    mysql> SET NAMES Latin1;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select txt from tbl;
    +---------+
    | txt     |
    +---------+
    | Québec  |
    | Québec  |
    +---------+
    2 rows in set (0.00 sec)
    

    如果验证通过,即您在使用默认字符集 Latin-1 时获得了所需的数据,那么您可以转储整个表以强制使用 --default-character-set=latin1,以便使用正确的数据创建文件,虽然带有错误的字符集规范

    但现在你可以替换标题行说明

    /*!40101 SET NAMES latin1 */;
    

    使用 UTF8。重新导入数据库就完成了。

    如果只有一些行受到影响,那就更难了:

    SELECT txt, CAST(CAST(txt AS CHAR CHARACTER SET Latin1) AS BINARY) AS utf8 FROM tbl;
    
    +-----------+---------+
    | txt       | utf8    |
    +-----------+---------+
    | Québec   | Québec  |
    +-----------+---------+
    1 row in set (0.00 sec)
    

    ...但是您在定位受影响的行时遇到了问题。您可能会发现一些代码点

    WHERE txt LIKE '%Ã%'
    

    但对于其他人,您必须手动采样。

    【讨论】:

      【解决方案2】:

      数据不会丢失。见this SQLFiddle example

      【讨论】:

      • 在 sql fiddle 中,您如何插入 latin1 编码的字符?在示例中,我只看到您插入了常规的 utf8。
      【解决方案3】:

      可以使用以下命令找到其他受影响的行:

      SELECT column
      FROM table
      WHERE NOT HEX(column) REGEXP '^([0-7][0-9A-F])*$'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-22
        • 1970-01-01
        • 2020-09-20
        • 1970-01-01
        • 2014-02-14
        • 2011-02-21
        相关资源
        最近更新 更多