首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >其中的字符集数据将存储在数据库中。

其中的字符集数据将存储在数据库中。
EN

Stack Overflow用户
提问于 2018-01-11 11:11:59
回答 3查看 1.1K关注 0票数 1

我的数据库在latin1中,排序规则是latin1_swedish_ci。在我的php文件中,我也使用iso-8859-1。但是,如果我存储了一些像“é”这样的字符,还有一些字符,我在下载内容时遇到了问题。因此,我们在utf8中添加了默认字符集,并在my.cnf文件中添加了跳字符集客户端握手。还在每次建立连接后和执行任何查询之前在查询中添加了“set-name utf8”。这解决了这个问题。但我做了如下观察

代码语言:javascript
复制
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脚本完成的。

代码语言:javascript
复制
$conn = mysqli_connect('<host>', '<username>', '<password>', 'table');<br/>
mysqli_query($conn, "SET NAMES 'utf8';");<br/>
mysqli_query($conn, 'insert into router.test values ("é");');<br/>

谢谢您的答复。

EN

回答 3

Stack Overflow用户

发布于 2018-01-11 12:10:21

我的数据库在latin1中,排序规则是latin1_swedish_ci。

这些是默认设置。在创建了列和表之后,每个列都有一个字符集和一个排序规则。更改默认值不会更改现有的列和表定义。

在我的php文件中,我使用iso-8859-1。

这没什么。Latin1 === iso-8859-1

但是,如果我存储了一些像“é”这样的字符,还有一些字符,我在下载内容时遇到了问题。

我猜您是指从表中检索内容并将其发送到web浏览器进行呈现的两步过程。这是可能是错误的第二步。尝试在php / html文件的head部分中设置它。

代码语言:javascript
复制
<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可能会带来麻烦。

票数 2
EN

Stack Overflow用户

发布于 2018-01-11 15:54:05

你的客户发送C3A9E9 -独立于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 storedhttp://mysql.rjweb.org/doc.php/charcoll

票数 1
EN

Stack Overflow用户

发布于 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;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48205711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档