我的数据库在latin1中,排序规则是latin1_swedish_ci。在我的php文件中,我也使用iso-8859-1。但是,如果我存储了一些像“é”这样的字符,还有一些字符,我在下载内容时遇到了问题。因此,我们在utf8中添加了默认字符集,并在my.cnf文件中添加了跳字符集客户端握手。还在每次建立连接后和执行任何查询之前在查询中添加了“set-name utf8”。这解决了这个问题。但我做了如下观察
Case 1:
Mysql conf file: No default character-set and no skip-character-set-client-handshake
Query: No set names
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | latin1 |<br/>
| character_set_connection | latin1 |<br/>
| character_set_database | latin1 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | latin1 |<br/>
| character_set_server | latin1 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
stored ->é(utf8)(Hex->C3A9)<br/>
Case2:
Mysql conf file: Default character-set - utf8 and no skip-character-set-client-handshake
Query: No set names<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | latin1 |<br/>
| character_set_connection | latin1 |<br/>
| character_set_database | utf8 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | latin1 |<br/>
| character_set_server | utf8 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
<br/>
stored ->é(utf8)(Hex->C3A9)<br/>
Case3:
Mysql conf file: Default character-set - utf8 and skip-character-set-client-handshake
Query: No set names<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | utf8 |<br/>
| character_set_connection | utf8 |<br/>
| character_set_database | utf8 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | utf8 |<br/>
| character_set_server | utf8 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(latin1)(Hex->E9)<br/>
Case4:
Mysql conf file: no Default characterset - utf8 and skip-character-set-client-handshake
Query: No set names<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | utf8 |<br/>
| character_set_connection | utf8 |<br/>
| character_set_database | utf8 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | utf8 |<br/>
| character_set_server | utf8 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(utf8)(Hex->C3A9)<br/>
Case5:
Mysql conf file: Default characterset - utf8 and skip-character-set-client-handshake
Query: set names utf8<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | utf8 |<br/>
| character_set_connection | utf8 |<br/>
| character_set_database | utf8 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | utf8 |<br/>
| character_set_server | utf8 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(latin1)(Hex->E9)<br/>
Case6:
Mysql conf file: Default characterset - utf8 and no skip-character-set-client-handshake
Query: set names utf8<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | latin1 |<br/>
| character_set_connection | latin1 |<br/>
| character_set_database | utf8 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | latin1 |<br/>
| character_set_server | utf8 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(latin1)(Hex->E9)<br/>
Case7:
Mysql conf file: no Default characterset and no skip-character-set-client-handshake
Query: set names utf8<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | latin1 |<br/>
| character_set_connection | latin1 |<br/>
| character_set_database | latin1 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | latin1 |<br/>
| character_set_server | latin1 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(latin1)(Hex->E9)<br/>
Case8:
Mysql conf file: no Default characterset and skip-character-set-client-handshake
Query: set names utf8<br/>
Result:
mysql> show variables like '%charac%';<br/>
+--------------------------+----------------------------+<br/>
| Variable_name | Value |<br/>
+--------------------------+----------------------------+<br/>
| character_set_client | latin1 |<br/>
| character_set_connection | latin1 |<br/>
| character_set_database | latin1 |<br/>
| character_set_filesystem | binary |<br/>
| character_set_results | latin1 |<br/>
| character_set_server | latin1 |<br/>
| character_set_system | utf8 |<br/>
| character_sets_dir | /usr/share/mysql/charsets/ |<br/>
+--------------------------+----------------------------+<br/>
8 rows in set (0.00 sec)<br/>
stored ->é(latin1)(Hex->E9)<br/>
Output containing all the 8 cases together<br/>
+-----------+------------------------------------------------------------------+<br/>
| HEX(name) | desc |<br/>
+-----------+------------------------------------------------------------------+<br/>
| C3A9 | no skip handshake and no default in conf and nothing in query |<br/>
| C3A9 | no skip handshake and default utf8 in conf and nothing in query |<br/>
| E9 | skip handshake and default utf8 in conf and nothing in query |<br/>
| C3A9 | skip handshake and no default in conf and nothing in query |<br/>
| E9 | skip handshake and default utf8 in conf and utf8 in query |<br/>
| E9 | no skip handshake and default utf8 in conf and utf8 in query |<br/>
| E9 | no skip handshake and no default in conf and utf8 in query |<br/>
| E9 | skip handshake and no default in conf and utf8 in query |<br/>
+-----------+------------------------------------------------------------------+<br/>数据存储在数据库中的依据是什么?有时以latin1格式存储,有时以utf8格式存储。它是基于选项(我指的是character_set_client、character_set_server等变量)还是基于my.cnf配置?
考虑到这8起案件,我还没有得出结论。我还对“设置名称”、“跳过字符集-客户-握手”进行了解释。但还是很困惑。在存储或仅显示时发生转换吗??
上面的观察是使用包含以下行的php脚本完成的。
$conn = mysqli_connect('<host>', '<username>', '<password>', 'table');<br/>
mysqli_query($conn, "SET NAMES 'utf8';");<br/>
mysqli_query($conn, 'insert into router.test values ("é");');<br/>谢谢您的答复。
发布于 2018-01-11 12:10:21
我的数据库在latin1中,排序规则是latin1_swedish_ci。
这些是默认设置。在创建了列和表之后,每个列都有一个字符集和一个排序规则。更改默认值不会更改现有的列和表定义。
在我的php文件中,我使用iso-8859-1。
这没什么。Latin1 === iso-8859-1
但是,如果我存储了一些像“é”这样的字符,还有一些字符,我在下载内容时遇到了问题。
我猜您是指从表中检索内容并将其发送到web浏览器进行呈现的两步过程。这是可能是错误的第二步。尝试在php / html文件的head部分中设置它。
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">如果您设置了它,并且所有的渲染都正确,那么您就完成了。您还可以将其设置为unicode并查看发生了什么。如果你不设置它,浏览器尝试猜测,使用神秘的规则。
因此,我们在utf8中添加了默认字符集,并在my.cnf文件中添加了跳字符集客户端握手。
同样,这不会更改表中的现有列。
数据存储在数据库中的依据是什么?
同样,根据为每一列选择的字符集。
有时以latin1格式存储,有时以utf8格式存储。
这是真的。
最佳实践:在创建每个表时,请提到字符集和排序规则。如果某些列有异常,则在创建这些列时请提及它们。
最佳实践:对于新数据库,请使用utfmb4。
最佳实践:始终设置数据库连接字符集。
最佳实践:了解如何在php中创建和操作unicode字符串。
最佳实践:当站起一个新的MySQL服务器时,将服务器范围内的默认值设置为utfmb4和utfmb4_general_ci。
不幸的是,将现有的php应用程序迁移到unicode可能会带来麻烦。
发布于 2018-01-11 15:54:05
你的客户发送C3A9或E9 -独立于MySQL所说的任何内容。
my.cnf和/或SET NAMES和/或连接参数决定SHOW VARIABLES LIKE 'character_set_%'中的3个值。
这些设置说明是将C3A9还是E9解释为latin1还是utf8
C3A9解释为utf8: good (é) C3A9,解释为latin1: Mojibake (é) E9,解释为latin1: good (é) E8,解释为utf8: String。
但我们还没结束..。
如果您是INSERTing,那么服务器将查看目标列的编码,并从上面的(latin1或utf8)转换为该列的声明。如果相同,则不需要转换,如果不同,则在存储期间进行转换。我很惊讶你没有偶然发现存储é的“双重编码”。当utf8字节(C3A9)被错误地通过SET NAMES (etc)声明为latin1,然后存储到utf8列中(因此又进行了另一次转换)时,就会发生这种情况。
更多讨论:Trouble with UTF-8 characters; what I see is not what I stored和http://mysql.rjweb.org/doc.php/charcoll
发布于 2018-01-12 13:26:57
感谢您的回复和链接@Rick。
事实上,我从其他链接中得到了我的问题的答案,也从里克·詹姆斯的分享链接中得到了答案。以上8例患者均满意。
如果连接(Utf8)和存储字符集(Latin1)之间存在差异,则MySQL将内容从一种编码转换为另一种编码。
案例1:在这里,我们实际上是将UTF-8字符写入latin1数据库,每个UTF-8字节序列将被解释为单独的latin1字符。组成UTF-8字符(C)的每个字节被解释为一个单独的latin1字符,每个字符在写入表时被转换为UTF-8 ((C) ->ƒA9 c -> c3 A9)。
也就是说,插入的字符串是é,在UTF-8 ( two )中,字符表示为两个字节,十六进制表示为C3A9。当我们将UTF-8数据插入到这个表中时,它只将发送的两个字节作为两个latin1字符处理,不进行转换,并将它们保存到表中。在对utf8进行设置名称之前,它以C3A9格式插入。
mysql>插入到test.test值中('é');
查询确定,1行受影响(0.00秒)
mysql>从测试中选择十六进制(文本);
+?
\x{e76f}六角(案文)
+?
C3A9
+?
一排设定(0.00秒)
案例2:当我们将任何试图插入到表中的数据设置为utf8时,它将被认为是utf8,因为目标列(文本)是latin1类型的,它将把utf8数据(2字节-> C3E9)转换为latin1 (1字节-> E9)。
mysql>设置名称‘utf8 8’;
查询确定,0行受影响(0.00秒)
mysql>插入到test.test值中('é');
查询确定,1行受影响(0.00秒)
mysql>从测试中选择十六进制(文本);
+?
\x{e76f}六角(案文)
+?
C3A9
E9
+?
2行设置(0.00秒)
因此,在对utf8执行设置名称之后,从客户端发送的任何数据,特别是像é这样的字符,都会以latin1格式本身转换和存储,而不是作为两个单独的latin1字符来处理。
另外,在获取数据时,它将转换回原来的格式。
设置名称指示客户端将使用哪个字符集向服务器发送SQL语句。因此,SET名称'utf8‘告诉服务器,“来自此客户端的未来传入消息处于字符集utf8中。”它还指定了服务器用于将结果发送回客户端的字符集。
集合名称'charset_name‘语句等效于以下三条语句:
集合character_set_client = charset_name;
集合character_set_results = charset_name;
集合character_set_connection = charset_name;
https://stackoverflow.com/questions/48205711
复制相似问题