10

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

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

我检查了双方的数据库属性:生产:显示创建数据库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_bin latin1_swedish_ci`的混合体and。它们有什么不同?有关系吗?

我也跑了:show variables like "character_set_database"得到了latin1

4

4 回答 4

11

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

第一的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

于 2012-01-05T22:28:48.020 回答
6

较旧的 WordPress 数据库甚至较新的 WordPress 数据库的一个常见问题是数据库表被设置为 latin-1,但内容实际上被编码为 UTF-8。如果您尝试导出为 UTF-8,MySQL 将尝试将(假定的)Latin-1 数据转换为 UTF-8,从而导致双编码字符,因为数据已经是 UTF-8。

解决方案是将表导出为 latin-1。由于 MySQL 认为它们已经是 latin-1,它会直接导出。

将字符集从“latin1”更改为“utf8”。由于转储的数据在导出过程中没有被转换,它实际上是 UTF-8 编码的数据。

将新表创建为 UTF-8 如果 CREATE TABLE 命令在 SQL 转储文件中,请将字符集从“latin1”更改为“utf8”。

正常导入数据。由于您的转储文件中有 UTF-8 编码的数据,因此转储文件中声明的字符集现在是 UTF-8,而您要导入的表是 UTF-8,一切都会顺利进行

于 2011-05-12T21:36:39.340 回答
4

我可以通过如下修改我的 wp-config.php 来解决这个问题:

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', 'utf8_general_ci' );
于 2014-06-30T05:43:51.997 回答
0

我认为您可以通过以下方式解决此问题:

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
$db = mysql_select_db('mysql_db', $link);
mysql_query('set names utf8', $link);
于 2011-05-12T21:35:15.007 回答