手机版

mysql中文乱码的一些解决方案

时间:2021-08-01 来源:互联网 编辑:宝哥软件园 浏览:

类型:E-tutorial大小:8.5M语言:中文评分:8.3标签:立即下载mysql时,我们难免会遇到这个问题:插入汉字时出现乱码。虽然这是一个很好的操作维护环境,但是在自己的机器上玩的时候,一定要时刻了解一二,不然以后怎么优雅地吹牛。

如果你遇到了这个问题,我们先不说原因,试试PC自带的cmd(或者mysql安装后的命令行客户端,或者上班用的SecureCRT)中的效果。进入mysql环境,从头开始。假设你的客户端代码是gbk或者utf8(这太不精确了,你怎么能假设呢?但一般来说,如果安装后还没有移动,cmd就是gbk代码,mysql安装后的命令行客户端是不会安装的。我不记得了,CRT会查看Session Options中的编码设置,通常会设置为utf8),并执行一些语句:

1.设置客户端编码、连接和返回结果的字符集,首先设置为latin1,

2.然后执行以下命令,看看每个字符是否是这样的。

如果您的character_set_client、character_set_connection和character_set_results不是latin1,您可以通过将它们设置为latin1来实现这一点,例如,设置character_set_client,并确保这三者都是latin1(这是第一步中的sql语句实际做的)。

3.当然,单独创建数据库db_latin1非常简单。测试它,并在创建时将数据库的代码设置为latin1。

4.在它下面创建一个table tab_latin1,字符集也设置为latin1。这里不设置字符是可以的。已经设置了数据库级别,这里只创建了一个名称字段。

5.在表格中插入一些汉字。首先说明一下这台机器的cmd代码是gbk,查看方式是右键属性-option,看当前代码页就知道了。

6.检查结果

看,中文显示正常~ ~ ~

好吧,你不想知道“为什么我不能这样设置?”你得往下看。上图:

我们知道mysql是一个客户端-服务器软件,每次客户端向服务器发送请求时,都可能会返回一些结果,插入其中的字符会经历一系列的转换。首先,客户端为我们编辑本身有一种代码。例如,PC端的命令行默认为gbk,PC端带有记事本的新文本文件默认为ANSI。对于记事本等常用的文本编辑器,我们可能会将默认代码设置为utf8,这意味着编辑器上的编辑是一种代码。

1.在客户端编辑后,首先转换为客户端对应的字符集,即上面打印的character_set_client变量指示的字符集;

2.向数据库服务发送请求,并将其转换为connection对应的连接字符集,即character_set_connection变量对应的字符集;

3.它存储在数据库中,并转换成存储在数据库中的字符集,可以是服务器级(character_set_server)、数据库级(character_set_database)或表级和列级(这里将详细描述);

4.数据库接收请求,执行查询得到结果,并再次转换为结果对应的字符集,即character_set_results变量指示,结果返回给客户端;

5.当结果来临时,是根据结果字符集进行编码的,所以让这个结果显示的客户端工具支持什么样的编码对我们来说也很重要,这决定了它对结果的解码方式。如果这个结果是utf8代码,返回给一个客户端,但是这个客户端只有ANSI代码,就不能正常显示。比如返回到SecureCRT,结果显示不正常,但是CRT支持多码,所以如果我们手动调整为utf8码,会再次正常显示,所以严格来说,这一步不是,只是和客户端条件有关。毕竟,当我们知道后,我们会将客户端调整为正常代码或原本支持转换结果的代码。

在上面的步骤3中,当从连接字符集编码转换到数据库存储中使用的编码时,有几种情况。一般在安装mysql的时候,尤其是安装32位版本的时候,有一个选择编码的步骤,大部分都会选择utf8编码。此时,系统可能会将一系列字符集变量设置为utf8,如character_set_server、character_set_connection和character_set_database。也就是说,这个character_set_server变量是在您启动mysql服务之前设置的,我们可以称之为服务器级编码。在构建表之前,我们必须首先创建一个数据库。创建数据库时,我们知道可以显式指定编码。例如,当我在开始创建它时,我明确指定了latin1字符集,或者没有指定它。如果未指定,将采用服务器级字符集,即character_set_server。同样,在创建表时,您也可以不指定代码。如果没有指定,可以使用数据库级代码和字符集数据库级。更类似地,在表中创建列字段时,也可以指定代码。如果不指定代码,将使用表级字符集。因此,这里有一个继承关系:

character _ set _ server=character _ set _ database=表中的字符集(无此变量)=字符集列(无此变量)

mysql创建的表可以细化到这四个级别,并不是每个级别都必须指定,而是默认使用更高级别的字符集(字符校对规则、排序规则也是如此,后面会解释)。

那么有没有可能没有指定character_set_server?如果没有在任何地方指定,尤其是在未安装的版本中,如果您忘记了,mysql在编译时默认使用latin1。为了应对这种情况,尤其是在未安装的版本中,在配置mysql时,经常需要手动配置mysql配置文件mysql.ini,包括其中的一个左右:

在配置文件中,采用默认的字符集,所以如果指定了character_set_server,默认采用,这样如果没有指定其他级别,就依次继承。

其他,character_set_filesystem:把操作系统上的字符转换成这个字符集,也就是把character_set_client转换成character_set_filesystem,默认是二进制的,但是不转换,character_set_system:这个变量总是utf8。是存储系统元字符的字符集,如表名、列名、用户名等。character_set_dir:显然它是一个表示目录的变量。打开这个目录,它存储了mysql的各种xml格式文件,用于编码字符集。解决乱码问题时可以忽略以上三个值。

嗯,转换过程和每个变量的含义都很清楚,所以需要找出哪些字符集代码可以转换,可以转换的字符也可能在一定的编码范围内,可以转换而不会乱码甚至损坏。如果损坏,就不能再正确显示。即使设置正确,恢复也不会回来。当然,关于角色之间的转换有很多情况,字符集太多了。您可以尝试在任意两个之间进行转换,但不能逐个列出。可以参考这篇文章:http://www.imcjd.com/? P=1324,对常用的字符转换做了一些转换比较和测试。

其中可以理解的是,完美匹配的转换肯定是没有问题的,例如,gbk-gbk、utf8-utf8、latin1-latin1;转换成单字节编码的latin1没有问题,比如gbk-latin1和utf8-latin1;单字节代码(latin1)转换为其他代码可能会导致某些范围内的转换不完整,例如latin1-gbk(非常特殊的中文),或者代码长度发生变化,例如latin1-utf8变成2、3等字节。

以下是另一篇文章(http://hi . Baidu.com/cuttinger/item/f4e 79726 a 60 ab 450 c 28d 59 da)中的一段。

[Latin1是一个非常常见的字符集。该字符集为单字节编码,向后兼容ASCII,编码范围为0x00-0xFF。0x00-0x7F与ASCII完全一致,0x80-0x9F为控制字符,0xA0-0xFF为文本符号。显然,latin1覆盖了所有单个字节。因此,任何字符串都可以保存在latin1字符集内,不需要担心内容因为不符合Latin1的编码标准而被丢弃。——gbk和utf8是多字节代码,没有这个功能。

Mysql用户经常使用latin1的这种全覆盖特性来保存其他类型的字符串,如gbk、utf8、big5等。在Latin1列中。保存过程中没有数据丢失,只要照原样取出,就是合法的gbk/utf8/大字符串。如果将gbk字符串保存在utf8列中,则gbk字符串中不符合utf8编码格式的内容将被丢弃,保存的内容无法原样取出,数据实际上会被销毁。

综上所述,如果我们看到一个字段的字符集是latin1,那么它可能是任意编码的字符串;如果字段的字符集是utf8或gbk,则应该是utf8或gbk ——,除非数据库用户使用不正确。】

我没有深入研究utf8和gbk编码的细节,这可能是不准确的。我只知道简单的ASCII编码(-_-),但我能了解整体情况。从上面的角度来看,latin1的单字节编码方法非常有用,其他编码可以转换成它,然后传输回来,不会丢失内容。所谓单字节编码就是一个一个来。我的理解是,比如圣诞节快到了,你得给姐姐送一盒苹果。为了营造浪漫,店铺提供了两种包装方式。一种是按数量,也就是把单个的苹果装在一个盒子里,一个接一个。这样,妹妹把所有的盒子都拆了之后,就可以完全恢复成一个完整无缺的苹果盒子了。另一种是限制每个箱子的重量。这样在包装的时候,如果只是三两重的话,完全可以放入一个盒子里,但是如果不够或者太多的话,就需要把苹果切开或者在盒子里加入其他的苹果。在这种情况下,无论你怎么打开盒子,你都会得到一盒碎苹果,因为当你遵循这种包装方法时,你已经破坏了单个苹果的完整性,现在你无法恢复它了~我们的字符集编码转换就是在做这种重新包装。

刚才提到的精确匹配情况是,当你买一盒苹果时,盒子里所有苹果的重量要么是两个,要么是三个,要么是六个,这样当你按重量包装时,当然只是分发,你仍然会得到完整的苹果。

所以说白了,两个可行的办法是:

1.所有变量都设置为latin1(设置名称latin1;),这样,即使我们使用各种编辑客户端代码(gbk或utf8),最终也能得到正确的结果;

2.所有设置均设置为gbk或gb2312(国标代码,仅限简体中文),采用完全匹配;

3.对于中间转换过程,如gbk输入,考虑将character_set_client和character_set_connection设置为latin1,将character_set_database设置为gb2312,在创建表时将字符集设置为gb2312。Character_set_results也可以设置为gb2312。当然,这只是一根鸡肋。本质上,使用latin1,gbk仅适用于转换为latin1然后转换为gb2312的简化型号。

最后,关于字符集校对规则我只知道一点点。我们在设置mysql字符集的时候,mysql会自动给出一个对应的校对规则,比如将charset设置为utf8,默认的排序规则是utf8_general_ci,gb2312字符集对应的是gb2312_chinese_ci,mysql命令检查所有的校对规则都是show排序规则,对应字符集的校对规则是show排序规则像‘utf8 %’。

字符集校对是使用当前字符集时使用的一种排序和比较方法。即使是同一个字符集,不同地区也不一样,所以有校对的说法,比如utf8_general_ci,不区分大小写,也就是不区分大小写。使用它进行校对时,当字段值匹配时,会出现案例记录。当然,还有其他规则。utf8打印很多,不是吗

版权声明:mysql中文乱码的一些解决方案是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。