UTF-8字符有问题;我看到的不是我存储的内容 [英] Trouble with UTF-8 characters; what I see is not what I stored

查看:53
本文介绍了UTF-8字符有问题;我看到的不是我存储的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用UTF-8,但遇到了问题。

我尝试了很多方法,以下是我得到的结果:

  • ????而不是亚洲字符。即使是欧洲文本,我也得到了Señor
  • 奇怪的胡言乱语(Mojibake?)例如Señor新浪新闻
  • 黑色钻石,如Se�或.
  • 最后,我遇到了数据丢失或至少被截断的情况:SeforSeñor
  • 即使我将文本放在外观正确时,它也无法正确地排序

我做错了什么?我如何修复代码?我是否可以恢复数据,如果可以,如何恢复?

推荐答案

此问题困扰着此网站的参与者以及其他许多人。

您已经列出了CHARACTER SET故障的五个主要案例。

最佳实践

接下来,最好使用CHARACTER SET utf8mb4COLLATION utf8mb4_unicode_520_ci。(有较新版本的Unicode排序规则正在进行中。)

utf8mb4utf8的超集,因为它处理的是4字节的UTF8代码,这是Emoji和一些中文用户需要的。

在MySQL之外,"UTF-8"是指所有大小的编码,因此实际上与MySQL的utf8mb4相同,而不是utf8

在下面的内容中,我将尝试使用这些拼写和大写来区分MySQL内部和外部。

应做的内容概述

  • 将您的编辑器等设置为UTF-8。
  • HTML表单的开头应类似<form accept-charset="UTF-8">
  • 将您的字节编码为UTF-8。
  • 将UTF-8设置为客户端中使用的编码。
  • 声明列/表CHARACTER SET utf8mb4(与SHOW CREATE TABLE核对。)
  • <meta charset=UTF-8>在HTML开头
  • 存储的例程获取当前的字符集/排序规则。它们可能需要重建。

UTF-8 all the way through

More details for computer languages(及其后续章节)

测试数据

不能使用工具或SELECT查看数据。 太多这样的客户端,尤其是浏览器,试图补偿不正确的编码,并向您显示正确的文本,即使数据库已损坏。 因此,选择一个包含一些非英文文本的表和列,并执行

SELECT col, HEX(col) FROM tbl WHERE ...

正确存储的UTF-8的十六进制将为

  • 表示空格(任何语言):20
  • 英文:4x5x6x7x
  • 对于大多数西欧国家,重音字母应为Cxyy
  • 西里尔语、希伯来语和波斯语/阿拉伯语:Dxyy
  • 亚洲大部分地区:Exyyzz
  • 表情符号和一些中文:F0yyzzww
  • More details

所见问题的具体原因和修复

截断文本(Se用于Señor):

  • 要存储的字节未编码为utf8mb4。解决此问题。
  • 还要检查阅读过程中的连接是否为UTF-8。

黑色钻石,带问号(Se�or表示Señor); 存在以下情况之一:

情况1(原始字节不是UTF-8):

  • 要存储的字节未编码为UTF8。解决此问题。
  • INSERTSELECT的连接(或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表示Señor):

  • 要存储的字节未编码为utf8/utf8mb4。解决此问题。
  • 数据库中的列不是CHARACTER SET utf8(或utf8mb4)。解决这个问题。(使用SHOW CREATE TABLE。)
  • 还要检查阅读过程中的连接是否为UTF-8。

Mojibake(SeñorforSeñor): (此讨论也适用于双重编码,但不一定可见。)

  • 要存储的字节需要进行UTF-8编码。解决此问题。
  • INSERTingSELECTing文本时的连接需要指定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

这篇关于UTF-8字符有问题;我看到的不是我存储的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆