mysql - 尽管字符集和发送的数据采用 UTF8 格式,数据库仍保存奇怪的字符

标签 mysql database utf-8 character-encoding mariadb

当我将某些字符保存到 MariaDB 数据库时,它们被存储为 2-4 个字符的字符串。

例如, 在数据库中保存为

来自包含我的表单的 html 页面的 head

<meta charset="utf-8">

当我检查发送到服务器的 header 时,它显示

Content-Type:text/html; charset=UTF-8

处理表单数据的 PHP 文件有

$mysqli->set_charset('utf8');

我已将数据库和表转换为 UTF8,方法是:

ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

检查information_schema表中的数据库和表详细信息,我可以看到数据库和表字符集是UTF8,默认排序规则名称是utf8_general_ci >.

但是错误编码的字符仍然被保存到数据库中。

我正在使用终端查看表数据,因此查看端的编码应该没有问题。

我还缺少什么?

==编辑==

回应@rick的评论 - 显示创建表search_templates;:

search_templates | CREATE TABLE `search_templates` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modified` timestamp NULL DEFAULT NULL,
  `template` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `space` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `secure` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

从 search_templates WHERE id = 25 中选择标题,十六进制(标题);:

+-----------------------+--------------------------------------------+
| title                 | HEX(title)                                 |
+-----------------------+--------------------------------------------+
| Kiddicare abc â„¢     | 4B69646469636172652061626320C3A2E2809EC2A2 |
+-----------------------+--------------------------------------------+

当通过十六进制到文本转换器时,它显示:Kiddicare abc Ⅲ

所以这些字符被这样保存到数据库中,这是否使问题变得更清楚?

==编辑==

根据@rick的建议(使用新添加的数据,因为之前的标题列已被删除):

SELECT title, CONVERT(BINARY(CONVERT( CONVERT(UNHEX(title) USING utf8) USING latin1)) USING utf8) FROM search_templates LIMIT 3;

->

+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
| title                                                                          | CONVERT(BINARY(CONVERT( CONVERT(UNHEX(title) USING utf8) USING latin1)) USING utf8) |
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
| Kids' Games & Toys » Toy Shop » Toys R Us                                    | NULL                                                                                |
| Kiddicare - Pushchairs | Prams | Car Seats | Baby Equipment | Online Baby Shop | NULL                                                                                |
| Kiddicare â„¢                                                                  | NULL                                                                                |
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+

最佳答案

CONVERT(BINARY(CONVERT(
    CONVERT(UNHEX('C3A2E2809EC2A2') USING utf8)
    USING latin1)) USING utf8) ==> '™'

该字符串末尾有一个“双重编码”商标。

这是重复的

Updating data in MySQL database after inserting in the wrong encoding

编辑

在上下文中,避免使用最里面的UNHEX;做

CONVERT(BINARY(CONVERT(
    CONVERT(title USING utf8)
    USING latin1)) USING utf8)

示例

CONVERT(BINARY(CONVERT(
    CONVERT('Kiddicare â„¢' USING utf8)
    USING latin1)) USING utf8)
-->  Kiddicare ™

但是,如果您可以重新加载数据并且数据是 utf8 编码的(看起来不是),那么始终使用 utf8 就是“正确的解决方案”。

关于mysql - 尽管字符集和发送的数据采用 UTF8 格式,数据库仍保存奇怪的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31123649/

相关文章:

mysql - MySQL 中键 "PRIMARY"的重复条目

mysql - 如何使 MySQL View 的创建遵循与数据库默认值相同的字符编码?

java - Mule 3.7.3 - Dataveawe 消息转换器编码错误

MySQL - 这两者中哪一个是更好的索引?

java - 如何安装SQLite JDBC驱动程序?

database - 多语言持久化关系图数据库是个好主意吗?

sql-server - 使用 SQL Server Management Studio 2005 导出时使用 UTF-8 编码保存 CSV

php - 如何按数据库中的两列分组?

mysql - 回退迭代 SQL 查询

javascript - 从 MySQL 查询 google map 上的位置数据