搜索
首页数据库mysql教程Windows服务器MySQL中文乱码的解决方法

Windows服务器MySQL中文乱码的解决方法

Jun 07, 2016 pm 04:28 PM
mysqlwindows中文乱码方法服务器解决

我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。 如果你也遇到了这个问题,咱先不谈原因,在PC自带的cmd中(或者是mysql安装版

 我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。

如果你也遇到了这个问题,咱先不谈原因,在PC自带的cmd中(或者是mysql安装版安装后的Command Line客户端,又或者是工作用的SecureCRT)试试效果。进入mysql环境,从头开始操作。假设你的客户端编码是gbk或者utf8(这么说太不严谨了,怎么能假设呢,但是一般来说假如安装后没动过,cmd是gbk编码,mysql安装后的Command Line客户端没装不记得,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. 在它下面创建一张表tab_latin1,字符集也设置成latin1,这里不设置字符也行,数据库级已经设置了,这里只创建一个name字段

5. 插入一些中文字符到表中,先说明,本机的cmd编码是gbk,查看方法是右键属性->选项,看下当前代码页即可知道

6. 查看下结果

看吧,正常显示中文了~~~

OK,都到这儿了你就不想知道“为什么我那样设置就是不行”么,当然得往下看看是不。上图:

我们知道mysql是客户端-服务器软件,每次操作都是客户端向服务端发送请求,然后可能会返回一些结果,这之间插入的字符经过了一系列转换。首先供我们编辑的客户端本身就有一种编码,比如PC端的命令行默认是gbk,PC自带notepad新建文本文件默认是ANSI,常用的文本编辑器如notepad++,我们可能会设置默认编码为utf8,就是说在编辑器上编辑,你所看到的本身就是一种编码了。

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

2. 向数据库服务发送请求,发送过程中,转化为connection对应连接字符集,即character_set_connection变量对应字符集;

3. 存储到数据库中,转化为数据库存储的字符集,可能是server级别(character_set_server)、database级别(character_set_database)或者表级别和列级别(这里还要细说下);

4. 数据库收到请求,执行查询得到结果,再次转化为results对应字符集,即character_set_results变量所指,该结果返回到客户端上;

5. 结果来了,是按照results字符集编码的,那我们让这个结果显示的客户端工具它支持什么样的编码也很重要,这决定了它如何去解码结果。假如这个结果是utf8编码,返回给某客户端了,但这个客户端只有ANSI编码,那当然不能显示正常,比如它返回到SecureCRT,结果显示不正常,但是CRT支持多种编码,我们手动将它调成utf8编码,那它就又显示正常了,所以严格来说这一步算不上,只是跟客户端条件有关,毕竟当我们知道后将客户端调整成正常的编码或者本来就支持转换results的编码后,这一步就不存在了。

在上面的第3步中,从连接字符集编码转化为数据库存储使用的编码时,要分几种情况,一般我们在装mysql时,特别是32位安装版本时,中间有一个选择编码的步骤,大多会选择utf8编码,这时系统就可能会把一系列的字符集变量均设置成了utf8,比如character_set_server、character_set_connection、character_set_database等等。也就是说这个character_set_server变量在你启动mysql服务的事先就被设置好了,我们可以称它为服务器级编码,那我们在建表前,先得创建数据库,在创建数据库时,我们知道可以显式指定编码的,比如最开头时我创建时显式指定采用latin1字符集,也可以不指定,如果不指定的话,它将采用服务器级的字符集,即character_set_server,同理在创建表时,也可不指定编码,不指定的话,采用数据库级编码,级character_set_database,更加同理在创建表中列字段时也可指定编码,不指定编码的话将采用表级别字符集,因此有这么一个继承关系在这:

character_set_server => character_set_database => character set in table(无此变量) => character set column(无此变量)

mysql创建表可以细化到这四个层次,不是每一层都必须指定,默认使用上一级的字符集(字符校对规则也是这样的,collation,稍后说明)。

那么有没有可能character_set_server没有指定呢,如果任何地方都没指定,特别是非安装版中,如果忘了,mysql在编译时默认采用latin1,为了应对这种情况,特别是非安装版本中在配置mysql时,经常需要手动配置mysql配置文件mysql.ini,其中就有大概这么一项:

在配置文件中默认采用的字符集,因此如果指定了character_set_server默认就会采用它,这样其他层次都不指定的话依次继承。

其他的,character_set_filesystem:把操作系统上的字符转换成此字符集,即把character_set_client转换成character_set_filesystem,默认为binary则不转换,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/f4e79726a60ab450c28d59da)中的一段。

【Latin1是一种很常见的字符集,这种字符集是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。很明显,Latin1覆盖了所有的单字节,因此,可以将任意字符串保存在latin1字符集中,而不用担心有内容不符合latin1的编码规范而被抛弃。——gbk和utf8是多字节编码,没有这种特性。

 mysql使用者经常利用Latin1的这种全覆盖特性,将其它类型的字符串,gbk,utf8,big5等,保存在latin1列中。保存的过程中没有数据丢失,只要原样取出来,便又是合法的gbk/utf8/big字符串。如果将gbk字符串保存在utf8列中,则gbk字符串中那些不符合utf8编码格式的内容,会被抛弃,保存的内容无法原样取出,数据实际上遭到了破坏。

 综上,如果我们看到一个字段的字符集是latin1的,那么,他保存的可能是任何编码的字符串;而一个字段的字符集是utf8或者gbk的,那么他保存的就应该是utf8或gbk的——除非数据库的使用者用错了。】

我没有深入学习过utf8、gbk编码的细节,极可能说的不准确,只知道简单的ASCII编码(-_-),但是可以了解个全局情况。从上面来看,latin1的单字节编码方式很有用,其他的编码可以转换为它再转回去而不至于丢失内容。所谓单字节编码就是挨着一个个来,我理解是,比如圣诞节到了,你要送妹子一箱苹果,为制造浪漫,商铺提供两种包装方式,一是按个数来,即单个苹果包装进一个盒子,来一个包装一个,这样,妹子在拆完所有的盒子后完完整整的可以还原为一个个完整的和一箱完好无损的苹果,二是按重量来,每个盒子限重2两、3两、6两,这样在包装时,若刚好重3两的当然可以完整的放进一个盒子,但是若不够或者多了,勉不了要切开苹果,或者再往盒子中添加其他的部分苹果,这样的话,妹子再无论怎样拆开盒子,都会得到一箱残缺不堪的苹果了,因为你在按照这种包装方式进行时,已经破坏了单个苹果的完整性,现在还原不回来了~我们的字符集编码转换就是在做这种重新包装的工作,latin1恰好就像单个苹果包装,而utf8就像第二种方式。

而刚才说的完全匹配的情况是,你去买一箱苹果,箱子里边的所有苹果重量已经恰好要么是2两,要么是3两或6两的,这样再按重量包装时当然就恰好分配了,得到的仍然是完整的苹果。

所以说白了,两种可行的方式是:

1. 所有变量均设置成latin1(set names 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,默认的collation就是utf8_general_ci,gb2312字符集对应gb2312_chinese_ci,mysql命令查看所有校对规则是show collation,查看某一对应字符集的校对规就是show collation like 'utf8%'了。

字符集校对是一种对使用当前字符集时采用的排序、对比方式,即便同一种字符集,在不同的地区也是不同的对比方式,所以才有校对这么一说,比如utf8_general_ci,这个ci就是case insensitive,即大小写不敏感,采用它校对时,查询某字段值匹配时,大小写的记录都会出现,当然还有其他的规则,utf8打印出来一大坨,不细研究了~

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)如何识别和优化MySQL中的慢速查询? (慢查询日志,performance_schema)Apr 10, 2025 am 09:36 AM

要优化MySQL慢查询,需使用slowquerylog和performance_schema:1.启用slowquerylog并设置阈值,记录慢查询;2.利用performance_schema分析查询执行细节,找出性能瓶颈并优化。

MySQL和SQL:开发人员的基本技能MySQL和SQL:开发人员的基本技能Apr 10, 2025 am 09:30 AM

MySQL和SQL是开发者必备技能。1.MySQL是开源的关系型数据库管理系统,SQL是用于管理和操作数据库的标准语言。2.MySQL通过高效的数据存储和检索功能支持多种存储引擎,SQL通过简单语句完成复杂数据操作。3.使用示例包括基本查询和高级查询,如按条件过滤和排序。4.常见错误包括语法错误和性能问题,可通过检查SQL语句和使用EXPLAIN命令优化。5.性能优化技巧包括使用索引、避免全表扫描、优化JOIN操作和提升代码可读性。

描述MySQL异步主奴隶复制过程。描述MySQL异步主奴隶复制过程。Apr 10, 2025 am 09:30 AM

MySQL异步主从复制通过binlog实现数据同步,提升读性能和高可用性。1)主服务器记录变更到binlog;2)从服务器通过I/O线程读取binlog;3)从服务器的SQL线程应用binlog同步数据。

mysql:简单的概念,用于轻松学习mysql:简单的概念,用于轻松学习Apr 10, 2025 am 09:29 AM

MySQL是一个开源的关系型数据库管理系统。1)创建数据库和表:使用CREATEDATABASE和CREATETABLE命令。2)基本操作:INSERT、UPDATE、DELETE和SELECT。3)高级操作:JOIN、子查询和事务处理。4)调试技巧:检查语法、数据类型和权限。5)优化建议:使用索引、避免SELECT*和使用事务。

MySQL:数据库的用户友好介绍MySQL:数据库的用户友好介绍Apr 10, 2025 am 09:27 AM

MySQL的安装和基本操作包括:1.下载并安装MySQL,设置根用户密码;2.使用SQL命令创建数据库和表,如CREATEDATABASE和CREATETABLE;3.执行CRUD操作,使用INSERT,SELECT,UPDATE,DELETE命令;4.创建索引和存储过程以优化性能和实现复杂逻辑。通过这些步骤,你可以从零开始构建和管理MySQL数据库。

InnoDB缓冲池如何工作,为什么对性能至关重要?InnoDB缓冲池如何工作,为什么对性能至关重要?Apr 09, 2025 am 12:12 AM

InnoDBBufferPool通过将数据和索引页加载到内存中来提升MySQL数据库的性能。1)数据页加载到BufferPool中,减少磁盘I/O。2)脏页被标记并定期刷新到磁盘。3)LRU算法管理数据页淘汰。4)预读机制提前加载可能需要的数据页。

MySQL:初学者的数据管理易用性MySQL:初学者的数据管理易用性Apr 09, 2025 am 12:07 AM

MySQL适合初学者使用,因为它安装简单、功能强大且易于管理数据。1.安装和配置简单,适用于多种操作系统。2.支持基本操作如创建数据库和表、插入、查询、更新和删除数据。3.提供高级功能如JOIN操作和子查询。4.可以通过索引、查询优化和分表分区来提升性能。5.支持备份、恢复和安全措施,确保数据的安全和一致性。

与MySQL中使用索引相比,全表扫描何时可以更快?与MySQL中使用索引相比,全表扫描何时可以更快?Apr 09, 2025 am 12:05 AM

全表扫描在MySQL中可能比使用索引更快,具体情况包括:1)数据量较小时;2)查询返回大量数据时;3)索引列不具备高选择性时;4)复杂查询时。通过分析查询计划、优化索引、避免过度索引和定期维护表,可以在实际应用中做出最优选择。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器