在 Latin1 数据库中存储 UTF8 文本的后果是啥?

Posted

技术标签:

【中文标题】在 Latin1 数据库中存储 UTF8 文本的后果是啥?【英文标题】:What are the ramifications of storing UTF8 text in a Latin1 database?在 Latin1 数据库中存储 UTF8 文本的后果是什么? 【发布时间】:2018-06-21 00:33:27 【问题描述】:

我有一个默认字符集latin1mysql数据库

mysql>  SELECT SCHEMA_NAME 'database', default_character_set_name 'charset', DEFAULT_COLLATION_NAME 'collation' FROM information_schema.SCHEMATA ;
+--------------------+---------+-------------------+
| database           | charset | collation         |
+--------------------+---------+-------------------+
| dbname12345        | latin1  | latin1_swedish_ci |

驱动程序,在本例中为 knex + node-mysql,配置为charset: 'utf8'。因此,驱动程序以 UTF8 对文本进行编码、存储和检索。

然而,mysql 认为数据在latin1。像这样混合字符集的后果是什么?

【问题讨论】:

如果将 UFT8 存储到 latin1 中,则会遇到编码问题。 什么编码问题?请更具体 UFT8 可以存储 latin1 无法存储的字符.. 取 UTF8 字符串 asdf ®´ 。如果我们用 utf8 将该字符串编码为 ASCII 字节,我们会得到asdf \xc2\xae\xc2\xb4,它作为十六进制字节是6173646620c2aec2b4。如果我们使用 latin1 对字符串进行编码,我们会得到 asdf \xae\xb4 ASCII 字节或 6173646620aeb4 十六进制字节。 Mysql 只是简单地存储和检索这些字节。如果我们的驱动程序知道如何将这些字符串编码和解码为这些字节,那么 mysql 字符集是什么又有什么关系呢? @david_adler "Unicode is a superset of ASCII" 所以有些字符可以存储在 unicode 中,而不能存储在 latin1 中。在这种情况下,使用非拉丁字符(例如普通话),不可能将其存储在 latin1 编码中。 【参考方案1】:

title 问题的简短回答是,可以将 latin1 和 utf8 的 common 的 256 个字符放入 CHARACTER SET 的任一列中。但是,您必须清楚您使用的是什么编码。否则® 可能会显示为®(“Mojibake”)。

不,SELECT 为该数据库中的任何 表获取 默认。它控制列的存储方式。

数据库有一个新表的默认值。 该表具有新列的默认值。 该列具有CHARACTER SETtrue 定义。

所以,请执行SHOW CREATE TABLE 并查看列。如果列未指定字符集,则查看位于输出末尾的表的默认值。 (还有一种方法可以从 information_schema.COLUMNS 获取此信息,但这种方法比较笨拙。)

® 是 latin1 中的十六进制 AE 或 utf8(或 utf8mb4)中的 C2AE。该字符在“ascii”字符集中不存在,它在 7 位处停止。

但是,由于® 存在于latin1utf8 中,您可以安全地在两种编码之间来回切换。也就是说,如果你告诉 MySQL 正确的东西。

client 中的编码在SET NAMES 或连接参数中指定。如果客户端有AE,则必须指定latin1;如果客户端有C2AE,则必须指定utf8。

同时,列(不是表,也不是数据库)可以是 latin1 或 utf8。如果需要,转换将在您 INSERTSELECT 时完成。

注意:latin1 只有 256 种不同的编码,没有中文,没有 Emoji,除了西欧字符几乎没有。

今后,最好定义大多数列utf8mb4。否则,可能会显示一堆便便(?????

如果遇到问号、Mojibake等,请咨询Trouble with UTF-8 characters; what I see is not what I stored

【讨论】:

以上是关于在 Latin1 数据库中存储 UTF8 文本的后果是啥?的主要内容,如果未能解决你的问题,请参考以下文章

FAQ系列 | utf8表存储latin1乱码字符转换

“字符串值不正确:”将 UTF8 文本插入 latin1 列时出现 MySQL 问题

在 PLPGSQL/Orafce 中转换文本

如何判断数据库中存储的是不是乱码

MySQL编码latin1转utf8

MySQL 将 latin1 数据转换为 UTF8