2

我们正在将包含 UTF-8 编码数据的 .sql 脚本中的数据导入 MySQL 数据库:

mysql ... database_name < script.sql

稍后,这些数据将再次以 UTF-8 格式显示在我们的 Web 应用程序(连接到该数据库)的页面上。但是在这个过程中的某个地方出了点问题,因为非 ascii 字符显示不正确。

我们第一次尝试解决它是将 mysql 列编码更改为 UTF-8(如此所述):

alter table wp_posts change post_content post_content LONGBLOB;`
alter table wp_posts change post_content post_content LONGTEXT CHARACTER SET utf8;

但这没有帮助。

最后,我们通过从带有附加命令行标志的 .sql 脚本导入数据解决了这个问题,我相信这会迫使 mysql 客户端将来自 .sql 脚本的数据视为 UTF-8。

mysql ... --default-character-set=utf8 database_name < script.sql

它有所帮助,但后来我们意识到这次我们忘记将列编码更改为 utf8 -latin1即使 utf-8 编码的数据正在流经数据库(从 sql 脚本到应用程序),它也被设置为。

因此,如果即使数据库字符集设置不正确,从数据库获取的数据也能正确显示,那我为什么还要费心设置正确的数据库编码呢?

特别想知道:

  1. 数据库的哪些部分依赖于列编码设置?这个设置什么时候有真正的意义?
  2. 在什么情况下进行列编码的隐式转换?
  3. 将列转换为二进制格式然后转换为目标编码的技巧如何工作(参见:上面的 sql 代码片段)?我还是不明白。

希望有人帮我清理一下...

4

1 回答 1

1

在我看来,最大的原因是它破坏了您的数据库一致性。

  • 它经常发生,您需要检查数据库中的数据。如果您不能正确地将来自网页的 UTF-8 字符串输入到您的 MySQL CLI 客户端,那就太可惜了;
  • 如果您需要使用 phpMyAdmin 通过“正确的”网络来管理您的数据库,那么您就是在限制自己(尽管可能不是问题);
  • 如果您需要为您的数据构建报告,那么您会受到可能选择的数量的极大限制,因为只有网络会产生正确的输出;
  • 如果您需要将部分数据库提取物交付给您的合作伙伴或外部公司进行分析,并且提取物被搞砸了 - 很遗憾。

现在回答你的问题:

  1. 当您向数据库询问ORDER BY某个字符串数据类型的列时,排序规则会考虑您的列的编码,因为如果您对不同的列有不同的编码,则可以应用一些内部转换。如果您尝试比较字符串,同样适用,编码信息在这里是必不可少的。编码与整理一起出现,尽管大多数人不经常使用此功能。

  2. 如前所述,如果您有任何不同编码的列集,数据库将选择将值隐式转换为通用编码,即现在的 UTF8。字符串的隐式编码可能在客户端框架/库中完成,具体取决于客户端的环境编码。通常,数据在发送到服务器时会重新编码为数据库的编码,并在传递结果时重新编码为客户端的编码。

  3. 二进制数据没有编码的概念,它只是一组字节。因此,当您转换为二进制时,您是在告诉数据库“忘记”编码,尽管您保持数据不变。稍后,您转换为强制正确编码的字符串。如果您确定数据在物理上是 UTF-8 格式,而由于某种意外指定了不同的编码,则此技巧会有所帮助。

Given that you've managed to load in data into the database by using --default-character-set=utf8 then there was something to do with your environment, I suggest it was not UTF8 setup.

I think the best practice today would be to:

  • have all your environments being UTF8 ready, including shells;
  • have all your databases defaulting to UTF8 encoding.

This way you'll have less field for errors.

于 2012-04-24T12:00:49.257 回答