mysql“set names latin1”似乎导致数据存储为utf8

vmdwslir  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(645)

我有一个表定义如下:

mysql> show create table temptest;
+------------+-----------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                  |
+------------+-----------------------------------------------------------------------------------------------------------+
| temptest | CREATE TABLE `temptest` (
  `mystring` varchar(100) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+------------+-----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

当我使用mysql控制台(通过mysql test)并通过

insert into temptest values ("é");

我可以看到它被保存为“拉丁1”编码

mysql> select hex(mystring) from temptest;
+---------------+
| hex(mystring) |
+---------------+
| E9            |
+---------------+

但是如果我发出一个“set names latin1”并执行相同的操作,我会看到它以utf8编码存储相同的字符。

mysql> set names latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into temptest values ("é");
Query OK, 1 row affected (0.01 sec)

mysql> select hex(mystring) from temptest;
+---------------+
| hex(mystring) |
+---------------+
| E9            |
| C3A9          |
+---------------+

据我所知,“set names”不应该影响mysql存储数据的方式(https://dev.mysql.com/doc/refman/8.0/en/set-names.html). 我错过了什么?对此有任何见解都将不胜感激。谢谢您。

hkmswyz6

hkmswyz61#

SET NAMES latin1 声明客户端中的编码为拉丁1。
但是(显然)它实际上是utf8。
所以,当你打字的时候 é ,客户端生成2个字节 C3 A9 .
然后将它们发送到服务器(mysqld),就好像它们是拉丁文1一样。
服务器说:“哦,我得到了一些拉丁1字节,我将把它们放入拉丁1列,所以我不需要转换它们。
两个拉丁字符 é (六角c3a9)。这叫莫吉巴克。
如果你这样做了 SET NAMES utf8 以及 SELECT 文本,你会“看到” é 它将是4个字节(十六进制) C383C2A9 )!
一句话:您的客户机编码实际上是utf8,所以您应该说 SET NAMES utf8 (或utf8mb4)。困惑的?欢迎来到俱乐部。

相关问题