UTF-8 字符问题;我看到的不是我储存的
Trouble with UTF-8 characters; what I see is not what I stored
我试过用UTF-8,运行遇到麻烦了。
我已经尝试了很多东西;这是我得到的结果:
????
而不是亚洲字符。即使对于欧洲文本,我也得到 Se?or
for Señor
.
- St运行ge 乱码(Mojibake?)例如
Señor
或 新浪新闻
for 新浪新闻
.
- 黑钻,如Se�or
- 最后,我遇到了数据丢失或至少被截断的情况:
Se
for Señor
。
- 即使我的文本看起来正确,它也没有排序正确。
我做错了什么?如何修复 code?我可以恢复 数据,如果可以,如何恢复?
这个问题困扰着这个网站的参与者,还有许多其他人。
您列出了 CHARACTER SET
麻烦的五个主要案例。
最佳实践
以后最好用CHARACTER SET utf8mb4
和COLLATION utf8mb4_unicode_520_ci
。 (管道中有更新版本的 Unicode 归类。)
utf8mb4
是 utf8
的超集,因为它处理 4 字节的 utf8 代码,这是表情符号和一些中文所需要的。
MySQL 之外,"UTF-8" 是指所有大小编码,因此实际上与 MySQL 的 utf8mb4
相同,而不是 utf8
。
我将在下文中尝试使用这些拼写和大写来区分内部和外部MySQL。
您应该做什么的概述
- 将您的编辑器等设置为 UTF-8。
- HTML 表格应以
<form accept-charset="UTF-8">
. 开头
- 将您的字节编码为 UTF-8。
- 将 UTF-8 设置为客户端使用的编码。
- 声明 column/table
CHARACTER SET utf8mb4
(检查 SHOW CREATE TABLE
。)
<meta charset=UTF-8>
开头HTML
- 存储例程获取当前 charset/collation。他们可能需要重建。
UTF-8 all the way through
More details for computer languages(及其后续部分)
测试数据
使用工具或 SELECT
查看数据是不可信的。
太多这样的客户端,尤其是浏览器,试图补偿不正确的编码,并向您显示正确的文本,即使数据库已损坏。
因此,选择一个 table 和包含一些非英语文本的列并执行
SELECT col, HEX(col) FROM tbl WHERE ...
正确存储的 UTF-8 的 HEX 将为
- 空白space(任何语言):
20
- 对于英语:
4x
、5x
、6x
或 7x
- 对于西欧大部分地区,重音字母应为
Cxyy
- 西里尔字母、希伯来字母和 Farsi/Arabic:
Dxyy
- 亚洲大部分地区:
Exyyzz
- 表情符号和一些中文:
F0yyzzww
- More details
所见问题的具体原因和修复方法
截断的 文本(Se
for Señor
):
- 要存储的字节未编码为utf8mb4。解决这个问题。
- 另外,检查读取时的连接是否为UTF-8。
Black Diamonds 带问号(Se�or
for Señor
);
存在其中一种情况:
案例 1(原始字节 不是 UTF-8):
- 要存储的字节未编码为utf8。解决这个问题。
INSERT
和 SELECT
的连接(或 SET NAMES
)不是 utf8/utf8mb4。解决这个问题。
- 此外,检查数据库中的列是否为
CHARACTER SET utf8
(或 utf8mb4)。
情况 2(原始字节 是 UTF-8):
SELECT
的连接(或 SET NAMES
)不是 utf8/utf8mb4。解决这个问题。
- 此外,检查数据库中的列是否为
CHARACTER SET utf8
(或 utf8mb4)。
仅当浏览器设置为 <meta charset=UTF-8>
时才会出现黑色菱形。
问号(普通的,不是黑钻)(Se?or
for Señor
):
- 要存储的字节未编码为utf8/utf8mb4。解决这个问题。
- 数据库中的列不是
CHARACTER SET utf8
(或utf8mb4)。解决这个问题。 (使用 SHOW CREATE TABLE
。)
- 另外,检查读取时的连接是否为UTF-8。
Mojibake(Señor
对于 Señor
):
(此讨论也适用于 Double Encoding,不一定可见。)
- 要存储的字节需要进行 UTF-8 编码。解决这个问题。
INSERTing
和SELECTing
文本连接时需要指定utf8或utf8mb4。解决这个问题。
- 列需要声明
CHARACTER SET utf8
(或utf8mb4)。解决这个问题。
- HTML 应该以
<meta charset=UTF-8>
开头。
如果数据看起来正确,但排序不正确,则
要么你选择了错误的归类,
或者没有适合您需要的排序规则,
或者你有 双重编码.
双重编码可以通过上述SELECT .. HEX ..
确认。
é should come back C3A9, but instead shows C383C2A9
The Emoji should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
也就是说,十六进制的长度大约是应有长度的两倍。
这是由于从 latin1(或其他)转换为 utf8,然后处理那些
字节,就好像它们是 latin1 并重复转换。
排序(和比较)不能正常工作,因为它是,例如,
排序就好像字符串是 Señor
.
尽可能修复数据
对于截断和问号,数据丢失。
对于Mojibake / 双重编码, ...
黑钻, ...
此处列出了修复。 (针对 5 种不同情况的 5 种不同修复;谨慎选择):http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
将代码 IDE 语言设置为 UTF-8
将 添加到您收集数据表单的网页 header。
检查您的 MySQL table 定义如下:
CREATE TABLE your_table (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8
如果您使用的是PDO,请确保
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8');
$dbL = new PDO($pdo, $user, $pass, $options);
如果您的数据库已经存在上述问题,您可以尝试使用 SIDU 以正确的字符集导出,然后以 UTF-8 导入。
根据服务器的设置方式,您必须相应地更改编码。你所说的 utf8 应该是最好的。但是,如果您遇到奇怪的字符,将网页编码更改为 ANSI 可能会有所帮助。
这在我设置 PHP MySQLi. This might help you understand more: ANSI to UTF-8 in Notepad++
时帮助了我
在服务器迁移后,我的两个项目也遇到了类似的问题。在搜索并尝试了很多解决方案之后,我遇到了这个:
mysqli_set_charset($con,"utf8");
将此行添加到我的配置文件后,一切正常!
我为 MySQLi—PHP mysqli set_charset() Function 找到了这个解决方案——当时我正在寻找解决来自 HTML 查询的插入问题。
我也在找同样的问题。我花了将近一个月的时间才找到合适的解决方案。
首先,您必须更新您的数据库,将所有最近的字符和排序规则更新为 utf8mb4 或至少支持 UTF-8 数据。
对于Java:
在建立 JDBC 连接时,将此添加到连接 URL useUnicode=yes&characterEncoding=UTF-8 作为参数,它会起作用。
对于Python:
在查询数据库之前,尝试在游标上强制执行此操作
*
cursor.execute('SET NAMES utf8mb4')
cursor.execute("SET CHARACTER SET utf8mb4")
cursor.execute("SET character_set_connection=utf8mb4")
*
如果它不起作用,请寻找正确的解决方案。
我试过用UTF-8,运行遇到麻烦了。
我已经尝试了很多东西;这是我得到的结果:
????
而不是亚洲字符。即使对于欧洲文本,我也得到Se?or
forSeñor
.- St运行ge 乱码(Mojibake?)例如
Señor
或新浪新闻
for新浪新闻
. - 黑钻,如Se�or
- 最后,我遇到了数据丢失或至少被截断的情况:
Se
forSeñor
。 - 即使我的文本看起来正确,它也没有排序正确。
我做错了什么?如何修复 code?我可以恢复 数据,如果可以,如何恢复?
这个问题困扰着这个网站的参与者,还有许多其他人。
您列出了 CHARACTER SET
麻烦的五个主要案例。
最佳实践
以后最好用CHARACTER SET utf8mb4
和COLLATION utf8mb4_unicode_520_ci
。 (管道中有更新版本的 Unicode 归类。)
utf8mb4
是 utf8
的超集,因为它处理 4 字节的 utf8 代码,这是表情符号和一些中文所需要的。
MySQL 之外,"UTF-8" 是指所有大小编码,因此实际上与 MySQL 的 utf8mb4
相同,而不是 utf8
。
我将在下文中尝试使用这些拼写和大写来区分内部和外部MySQL。
您应该做什么的概述
- 将您的编辑器等设置为 UTF-8。
- HTML 表格应以
<form accept-charset="UTF-8">
. 开头
- 将您的字节编码为 UTF-8。
- 将 UTF-8 设置为客户端使用的编码。
- 声明 column/table
CHARACTER SET utf8mb4
(检查SHOW CREATE TABLE
。) <meta charset=UTF-8>
开头HTML- 存储例程获取当前 charset/collation。他们可能需要重建。
UTF-8 all the way through
More details for computer languages(及其后续部分)
测试数据
使用工具或 SELECT
查看数据是不可信的。
太多这样的客户端,尤其是浏览器,试图补偿不正确的编码,并向您显示正确的文本,即使数据库已损坏。
因此,选择一个 table 和包含一些非英语文本的列并执行
SELECT col, HEX(col) FROM tbl WHERE ...
正确存储的 UTF-8 的 HEX 将为
- 空白space(任何语言):
20
- 对于英语:
4x
、5x
、6x
或7x
- 对于西欧大部分地区,重音字母应为
Cxyy
- 西里尔字母、希伯来字母和 Farsi/Arabic:
Dxyy
- 亚洲大部分地区:
Exyyzz
- 表情符号和一些中文:
F0yyzzww
- More details
所见问题的具体原因和修复方法
截断的 文本(Se
for Señor
):
- 要存储的字节未编码为utf8mb4。解决这个问题。
- 另外,检查读取时的连接是否为UTF-8。
Black Diamonds 带问号(Se�or
for Señor
);
存在其中一种情况:
案例 1(原始字节 不是 UTF-8):
- 要存储的字节未编码为utf8。解决这个问题。
INSERT
和SELECT
的连接(或SET NAMES
)不是 utf8/utf8mb4。解决这个问题。- 此外,检查数据库中的列是否为
CHARACTER SET utf8
(或 utf8mb4)。
情况 2(原始字节 是 UTF-8):
SELECT
的连接(或SET NAMES
)不是 utf8/utf8mb4。解决这个问题。- 此外,检查数据库中的列是否为
CHARACTER SET utf8
(或 utf8mb4)。
仅当浏览器设置为 <meta charset=UTF-8>
时才会出现黑色菱形。
问号(普通的,不是黑钻)(Se?or
for Señor
):
- 要存储的字节未编码为utf8/utf8mb4。解决这个问题。
- 数据库中的列不是
CHARACTER SET utf8
(或utf8mb4)。解决这个问题。 (使用SHOW CREATE TABLE
。) - 另外,检查读取时的连接是否为UTF-8。
Mojibake(Señor
对于 Señor
):
(此讨论也适用于 Double Encoding,不一定可见。)
- 要存储的字节需要进行 UTF-8 编码。解决这个问题。
INSERTing
和SELECTing
文本连接时需要指定utf8或utf8mb4。解决这个问题。- 列需要声明
CHARACTER SET utf8
(或utf8mb4)。解决这个问题。 - HTML 应该以
<meta charset=UTF-8>
开头。
如果数据看起来正确,但排序不正确,则 要么你选择了错误的归类, 或者没有适合您需要的排序规则, 或者你有 双重编码.
双重编码可以通过上述SELECT .. HEX ..
确认。
é should come back C3A9, but instead shows C383C2A9
The Emoji should come back F09F91BD, but comes back C3B0C5B8E28098C2BD
也就是说,十六进制的长度大约是应有长度的两倍。
这是由于从 latin1(或其他)转换为 utf8,然后处理那些
字节,就好像它们是 latin1 并重复转换。
排序(和比较)不能正常工作,因为它是,例如,
排序就好像字符串是 Señor
.
尽可能修复数据
对于截断和问号,数据丢失。
对于Mojibake / 双重编码, ...
黑钻, ...
此处列出了修复。 (针对 5 种不同情况的 5 种不同修复;谨慎选择):http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases
将代码 IDE 语言设置为 UTF-8
将 添加到您收集数据表单的网页 header。
检查您的 MySQL table 定义如下:
CREATE TABLE your_table ( ... ) ENGINE=InnoDB DEFAULT CHARSET=utf8
如果您使用的是PDO,请确保
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8'); $dbL = new PDO($pdo, $user, $pass, $options);
如果您的数据库已经存在上述问题,您可以尝试使用 SIDU 以正确的字符集导出,然后以 UTF-8 导入。
根据服务器的设置方式,您必须相应地更改编码。你所说的 utf8 应该是最好的。但是,如果您遇到奇怪的字符,将网页编码更改为 ANSI 可能会有所帮助。
这在我设置 PHP MySQLi. This might help you understand more: ANSI to UTF-8 in Notepad++
时帮助了我在服务器迁移后,我的两个项目也遇到了类似的问题。在搜索并尝试了很多解决方案之后,我遇到了这个:
mysqli_set_charset($con,"utf8");
将此行添加到我的配置文件后,一切正常!
我为 MySQLi—PHP mysqli set_charset() Function 找到了这个解决方案——当时我正在寻找解决来自 HTML 查询的插入问题。
我也在找同样的问题。我花了将近一个月的时间才找到合适的解决方案。
首先,您必须更新您的数据库,将所有最近的字符和排序规则更新为 utf8mb4 或至少支持 UTF-8 数据。
对于Java:
在建立 JDBC 连接时,将此添加到连接 URL useUnicode=yes&characterEncoding=UTF-8 作为参数,它会起作用。
对于Python:
在查询数据库之前,尝试在游标上强制执行此操作
*
cursor.execute('SET NAMES utf8mb4')
cursor.execute("SET CHARACTER SET utf8mb4")
cursor.execute("SET character_set_connection=utf8mb4")
*
如果它不起作用,请寻找正确的解决方案。