迁移后,我正在尝试修复数据库中字符字段的一些损坏。我怀疑部分问题是带有 UTF-8 数据的字段是用 MySQLlatin1
字符集解释的。在我尝试解决问题之前,我想了解它。其中一部分是要准确理解latin1
字符集是什么。
latin1
MySQL 8.0 和 MySQL 5.7 中字符集的代码点(字节值)和字符之间映射的正式定义是什么?如果整理很重要,我会接受latin1_swedish_ci
整理的答案。
latin1
据说与Windows CP-1252编码相同。在关于 CP-1252 的 Wikipedia 文章中,有一个 256 字节码值的表格,表格的每个单元格中都有一个字符。这就是我所追求的那种定义。但是,我希望有比“它与 CP-1252 相同”和“维基百科中的那个表可能是准确的”更严格的东西。
我试过浏览 MySQL 文档。我希望10.10.2 West European Character Sets想要正式的定义,但我在那里看不到。我在这里或维基百科上也没有看到答案。
如果有一个 MySQL 源文件定义了latin1
,并且我可以通过 URL 查看该源文件,那可能就足够了。但如果有人组成了一个 256 单元格的表格,那就更好了。
如果你没有正确告诉 MySQL客户端的编码,各种形式的乱码——Mojibake、截断、问号等——可能会发生。有关该领域的帮助,请参阅https://stackoverflow.com/questions/38363566/trouble-with-utf8-characters-what-i-see-is-not-what-i-stored 对于“腐败”,我建议开始接着就,随即。
这张表是否足以看到 latin1 和 UTF-8 之间的映射?它是“256 单元表”的前 128 位吗? http://mysql.rjweb.org/doc.php/charcoll#8_bit_encodings 它有十进制、latin1 hex、utf8 hex、可打印字符、htmlentity 列。在网上搜索“ascii”;有无数页显示底部 28。
这不是一个正式的定义;我有时用它作为在这个论坛上回答问题的拐杖。
URL 应该使用 PHP
urlencode()
(或等效的)编码,它将 8 位代码转换为 3 个字符:'%' 加上两个十六进制字符。至于
latinx
vsCPxxxx
,似乎有极少数字符不完全匹配;通常在 8x 或 9x 范围内。“它相同”已经足够好,因为主要差异(例如216 D8 C398 Ø Ø
)非常明显。UTF-8 是在欧元成为标准货币之前发明的。因此“80”曾经是(并且可能仍然是)一个不同点:
128 80 E282AC € €
注意 3 字节的 UTF-8 编码。我经常遇到吐出奇怪空格的 Microsoft Word 文档
160 A0 C2A0
。Hex 20 是一个普通的空间。打开高位,你会得到A0
,这似乎等同于 HTML
(不间断空格)。UTF-8 解析器会吐出一个普通A0
的C2A0
.如果找不到规范,回答问题的一种方法是测试系统。以下查询从
00
to生成代码单元(字节值)FF
,使用编码将它们解释为字符latin1
,然后提供代码单元、字符、Unicode 标量值表(可以在Unicode 标准的字符代码图表中查找) ),以及 UTF-8 代码单元(字节):这是我在我的 MySQL 8.0.30 副本上运行此查询时得到的结果: