mysql - 可怕的 MySQL 导入编码问题 - 重新审视

标签 mysql sql wordpress character-encoding database-migration

我遇到了标准 MySQL 导入编码问题,但似乎无法解决。

我的客户已经运行了一段时间的 WordPress 安装。我已将数据库转储到文件中,并在本地导入。生成的页面中到处都是 � 字符。

我检查了双方的数据库属性: 制作:show create database wordpress;

CREATE DATABASE `wordpress` /*!40100 DEFAULT CHARACTER SET latin1 */

本地:显示创建数据库 wordpress;

CREATE DATABASE `wordpress` /*!40100 DEFAULT CHARACTER SET latin1 */

生产:显示创建表 wp_posts;

CREATE TABLE `wp_posts` (
  `ID` bigint(20) unsigned NOT NULL auto_increment,
  ...
  KEY `post_date_gmt` (`post_date_gmt`)
) ENGINE=MyISAM AUTO_INCREMENT=7932 DEFAULT CHARSET=utf8

本地:显示创建表 wp_posts;

CREATE TABLE `wp_posts` (
  `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  ...
  KEY `post_date_gmt` (`post_date_gmt`)
) ENGINE=MyISAM AUTO_INCREMENT=7918 DEFAULT CHARSET=utf8

我已经花了几个小时阅读有关如何压缩 � 的论坛,但我什么也做不了。 99% 的答案说要匹配数据库之间的字符集。如果满足以下条件,我认为应该可行:

mysqldump --opt --compress --default-character-set=latin1 -uusername -ppassword wordpress | ssh username@anotherserver.net mysql --default-character-set=latin1 -uusername -ppassword wordpress

我也使用 utf8 字符集完成了它。仍然是�的。

我尝试直接修改 SQL 转储,将 utf8latin1 放在“SET names UTF8”行中。仍然是�的。

奇怪的症状

我希望这些 � 字符出现在内容中的特殊字符的位置,例如 ñö,但我已经在通常出现的地方看到了只是一个空间。我还看到它代替撇号(但不是所有撇号)、双引号和商标符号。

� 标记非常罕见。它们平均每页出现三到四次。

通过 Sequel Pro(本地或实时)查看数据库时,我没有看到任何 �。通过 Textmate 查看时,我在 SQL 中没有看到任何 �。

我错过了什么?

编辑

更多信息:

我试图确定实时数据库认为编码是什么。我运行了show table status,似乎排序规则是utf8_general_ci、utf8_binlatin1_swedish_ci`的混合体。它们有什么不同?有关系吗?

我也跑了:show variables like "character_set_database" and got latin1;

最佳答案

这就是我最终解决问题的方式:

第一个 mysqldump -uusername -ppassword --default-character-set=latin1 database -r dump.sql

然后运行这个脚本:

$search = array('/latin1/');
$replace = array('utf8');
foreach (range(128, 255) as $dec) {
    $search[] = "/\x".dechex($dec)."/";
    $replace[] = "&#$dec;";
}

$input = fopen('dump.sql', 'r');
$output = fopen('result.sql', 'w');

while (!feof($input)) {
    $line = fgets($input);
    $line = preg_replace($search, $replace, $line);
    fwrite($output, $line);
}

fclose($input);
fclose($output);

脚本查找所有大于 127 的十六进制字符并将它们编码到它们的 HTML 实体中。

然后 mysql -uusername -ppassword database < result.sql

关于mysql - 可怕的 MySQL 导入编码问题 - 重新审视,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5984697/

相关文章:

python - select from where mysql 语句中的语法错误

php - ID 不是整数... EasyAPNS

sql - 如果我有一个永远不会到达的合法代码,为什么 SQL 会抛出错误?

wordpress - "order already paid"在 Woocommerce 中使用 Paypal 结账

mysql - liferay使用mysql时出现错误

php - 从按钮发送数据到 php 页面并发布结果

mysql - SQL - 按条目 X 彼此间隔的时间对表进行分组

mysql - 如何在不在查询中的情况下获得更好的性能

javascript - 使用 Javascript 和 PHP 的 24 小时倒计时器

php - WordPress 代码未发生更改