前言:什么是mysql中的中文乱码问题?

  话不多说,直接上图

  这个东西困扰了我好久,导致我现在对windows映像非常不好,所以就想改成Linux,行了,牢骚就发到这里,直接说问题,明眼人一眼就看出来是编码问题,但是,不多说,继续上图

  明明都设置成了utf8了,可是还是出现了乱码问题。不是说为了避免所有乱码问题,应该采用UTF-8,将来要支持国际化也非常方便,可是为什么还出现这个问题。

一,关于GBK,GB2312,UTF8的介绍

  1. UTF- 8Unicode Transformation Format-8bit
  2. 允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对
  3. 英文使用8位(即一个字节),中文使用24位(三个字节)来编码。UTF-8包含全
  4. 世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在
  5. 各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文
  6. IE上也能显示中文,他们无需下载IE的中文语言支持包。
  7.  
  8. GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。
  9. GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,
  10. 为了区分中文,将其最高位都设定成1GBK包含全部中文字符,是国家编码,通
  11. 用性比UTF8差,不过UTF8占用的数据库比GBK大。

  三者之间的转化

GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:

  1. GBKGB2312--Unicode--UTF8
  2.  
  3. UTF8--Unicode--GBKGB2312

  对于一个网站、论坛来说,如果英文字符较多,则建议使用UTF-8节省空间。不过现在很多论坛的插件一般只支持GBK。

GB2312是GBK的子集,GBK是GB18030的子集
GBK是包括中日韩字符的大字符集合
如果是中文的网站 推荐GB2312 ,GBK有时还是有点问题
为了避免所有乱码问题,应该采用UTF-8,将来要支持国际化也非常方便
UTF-8可以看作是大字符集,它包含了大部分文字的编码。
使用UTF-8的一个好处是其他地区的用户(如香港台湾)无需安装简体中文支持就能正常观看你的文字而不会出现乱码。

  1. gb2312是简体中文的码
  2.  
  3. gbk支持简体中文及繁体中文
  4.  
  5. big5支持繁体中文
  6.  
  7. utf-8支持几乎所有字符

二,如何查询mysql字符集设置情况

  我们在mysql中输入下面命令:

  1. mysql> show variables like '%char%';

  结果:

  1. +--------------------------+---------------------------------------------------------+
  2. | Variable_name | Value |
  3. +--------------------------+---------------------------------------------------------+
  4. | character_set_client | utf8 |
  5. | character_set_connection | utf8 |
  6. | character_set_database | utf8 |
  7. | character_set_filesystem | binary |
  8. | character_set_results | utf8 |
  9. | character_set_server | utf8 |
  10. | character_set_system | utf8 |
  11. | character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.5\share\charsets\ |
  12. +--------------------------+---------------------------------------------------------+
  13. 8 rows in set (0.00 sec)

  在查询结果中可以看到mysql 数据库系统中客户端、数据库连接、数据库、文件系统、查询结果、服务器、系统的字符集设置在这里,文件系统字符集是固定的,系统、服务器的字符集在安装时确定,与乱码问题无关。乱码的问题与客户端、数据库连接、数据库、查询结果的字符集设置有关。从上图中可以看到 MySQL 有六处使用了字符集,分别为:client 、connection、database、results、server 、system。其中与服务器端相关:database、server、system(永远无法修改,就是utf-8);与客户端相关:connection、client、results 。

client 为客户端使用的字符集。
connection 为连接数据库的字符集设置类型,如果程序没有指明连接数据库使用的字符集类型则按照服务器端默认的字符集设置。
database 为数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将使用服务器安装时指定的字符集设置。
results 为数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集。
server 为服务器安装时指定的默认字符集设定。
system 为数据库系统使用的字符集设定。

三,MySQL中编码转换的思路

如图:

  *注:客户端是看访问mysql 数据库的方式,通过命令行访问,命令行窗口就是客户端,通过JDBC 等连接访问,程序就是客户端我们在向mysql 写入中文数据时,在客户端、数据库连接、写入数据库时分别要进行编码转换。在执行查询时,在返回结果、数据库连接、客户端分别进行编码转换。现在我们应该清楚,乱码发生在数据库、客户端、查询结果以及数据库连接这其中一个或多个环节。

举个例子:

  1. 现在有一个utf8 编码数据库,客户端连接使用GBK 编码,connection 使用默认
  2. ISO8859-1(也就是mysql 中的latin1),我们在客户端发送"中文"这个字符串,
  3. 客户端将发送一串GBK 格式的二进制码给connection 层,connection
  4. ISO8859-1 格式将这段二进制码发送给数据库,数据库将这段编码以utf8
  5. 格式存储下来,我们将这个字段以utf8格式读取出来,肯定是得到乱码,也就是
  6. 说中文数据在写入数据库时是以乱码形式存储的,在同一个客户端进行查询操作时,
  7. 做了一套和写入时相反的操作,错误的utf8 格式二进制码又被转换成正确的GBK
  8. 码并正确显示出来。
  9.  

  

四,MySQL中涉及的字符集详解

  1. character-set-server/default-character-set:服务器字符集,默认情况下所采用的。
  2.  
  3. character-set-database:数据库字符集。
  4.  
  5. character-set-table:数据库表字符集。

  优先级依次增加。所以一般情况下只需要设置character-set-server,而在创建数据库和表时不特别指定字符集,这样统一采用character-set-server字符集。

  1. character-set-client:客户端的字符集。客户端默认字符集。
  2. 当客户端向服务器发送请求时,请求以该字符集进行编码。
  3.  
  4. character-set-results:结果字符集。服务器向客户端返回结果或者信息时,结果以该字符集进行编码。

  
  在客户端,如果没有定义character-set-results,则采用character-set-client字符集作为默认的字符集。所以只需要设置character-set-client字符集。

  要处理中文,则可以将character-set-server和character-set-client均设置为GB2312,如果要同时处理多国语言,则设置为UTF8。

  1. 系统变量:
  2. character_set_server:默认的内部操作字符集
  3.  
  4. character_set_client:客户端来源数据使用的字符集
  5.  
  6. character_set_connection:连接层字符集
  7.  
  8. character_set_results:查询结果字符集
  9.  
  10. character_set_database:当前选中数据库的默认字符集
  11.  
  12. character_set_system:系统元数据(字段名等)字符集

  

  解决乱码的方法是,在执行SQL语句之前,将MySQL以下三个系统参数设置为与服务器字符集character-set-server相同的字符集。

  1. character_set_client:客户端的字符集。
  2.  
  3. character_set_results:结果字符集。
  4.  
  5. character_set_connection:连接字符集。

  
设置这三个系统参数通过向MySQL发送语句:

  1. set names gb2312
  2.  
  3. set character_set_client = 字符集
  4.  
  5. set character_set_connection = 字符集
  6.  
  7. set character_set_results = 字符集

五,设置MySQL的字符编码

  这里我已经将MySQL的数据库编码设置为UTF-8,所以下面现实的都是UTF-8。

  设置MySQL数据库的编码方式有三种,分别是基于session会话的、基于全局gloable的、永久性改变的。

5.1 基于session会话层

1.首先连接到MySQL :

  1. mysql -uroot -proot

  

2.输入\s,即可查看数据库的字符编码

  

3.查看数据库的详细编码

  输入:

  1. show variables like '%char%';

  

   

4.新建一个数据库查看数据库编码

  1.   create database test1;
  2.   show create database test1;

  

  

5.设置当前窗口的数据库字符编码,即使基于会话session级别的,关闭此窗口,重新打开另外的窗口操作数据库依然是原来的字符编码

  这里将utf-8设置为gbk:

  1.   set character_set_database=gbk;
  2.   set character_set_server=gbk;
  3.     show variables like '%char%';

  

  

我们发现database和server都变成了gbk,然后我们再重新创建一个数据库,查看其编码,

  1.   create dabase test2;
  2.   show create dabase test2;

  

   

  我们发现数据库编码已经变为gbk了。

  但是我们将此窗口关闭后,重新打开一个新的窗口来连接数据库,重新查看数据库的编码,发现不是我们刚刚修改的gbk了,还是原来的utf-8。如图:

   

  因为是基于会话级别的改变编码的方式,当重新新建一个窗口连接的时候,会话已经改变,所以变为了原来的字符编码。

5.2 设置全局编码,永久性改变

1.设置全局的数据库字符编码,即使基于整个MySQL服务的,当重启MySQL服务的时候,编码依然会变为原来的字符编码

  1.   set global character_set_database=gbk;
  2.   set global character_ser_server=gbk;
  3.   show variables like '%char%';

  

   

  我们发现数据库的编码没有修改成功,还是原来的utf-8。但是当我们重新创建数据库或者重新创建表的时候,编码就会是我们所期望的gbk了。

  在本窗口的新建数据库是肯定可以的,session级别的都可以,全局的肯定ok的。重点是在另一个窗口中的编码现实的是什么,下面我们复制一个窗口,新建数据库,来查看数据库和表的编码

  1.   create database test3;
  2.   show variables like '%char%';

  

   

  我们发现这是没有问题的。

  但是我们重启MySQL数据库的时候,编码又是回复为原来的utf-8了。

2.设置永久的字符编码,即需要在配置文件中修改数据库的字符编码

  编辑 /etc/my.cnf,

    在里面加入,已经有[XXX]的,在里面直接加入即可。

  1.     [mysqld]
  2.     character-set-server=utf8 
  3.     [client]
  4.     default-character-set=utf8 
  5.     [mysql]
  6.     default-character-set=utf8

  

  然后重启数据库即可,service mysql restart.

一定要注意:修改完的数据库和库里的表 并不会使原来的数据生效,而是新加入的数据才会生效。

5.3 一劳用逸

  在 MySQL 的安装目录下有一个 my.ini 配置文件,通过修改这个配置文件可以一劳永逸的解决乱码问题。在这个配置文件中 [mysql] 与客户端配置相关,[mysqld] 与服务器配置相关。默认配置如下:

  1. [mysqld]
  2. character-set-server=utf8
  3. collation-server=utf8_general_ci
  4. [client]
  5. default-character-set=utf8
  6. [mysql]
  7. default-character-set=utf8

  这时只需要将下的默认编码 default-character-set=utf8 改为 default-character-set=gbk ,重新启动 MySQL 服务即可。

  1. [mysqld]
  2. character-set-server=utf8
  3. collation-server=utf8_general_ci
  4. [client]
  5. default-character-set=gbk
  6. [mysql]
  7. default-character-set=gbk

  修改之后,直接上图:

5.4  修改数据库字符编码

  1. mysql> alter database mydb character set utf8 ;

  

六,检测字符集问题的一些手段

  1. SHOW CHARACTER SET;
  2.  
  3. SHOW COLLATION;
  4.  
  5. SHOW VARIABLES LIKE character%’;
  6.  
  7. SHOW VARIABLES LIKE collation%’;
  8.  
  9. SQL函数HEXLENGTHCHAR_LENGTH
  10.  
  11. SQL函数CHARSETCOLLATION

  

使用MySQL字符集时的建议

• 建立数据库/表和进行数据库操作时尽量显式指出使用的字符集,而不是依赖于MySQL的默认设置,否则MySQL升级时可能带来很大困扰;

• 数据库和连接字符集都使用latin1时虽然大部分情况下都可以解决乱码问题,但缺点是无法以字符为单位来进行SQL操作,一般情况下将数据库和连接字符集都置为utf8是较好的选择;

• 使用mysql C API时,初始化数据库句柄后马上用mysql_options设定MYSQL_SET_CHARSET_NAME属性为utf8,这样就不用显式地用 SET NAMES语句指定连接字符集,且用mysql_ping重连断开的长连接时也会把连接字符集重置为utf8;

• 对于mysql PHP API,一般页面级的PHP程序总运行时间较短,在连接到数据库以后显式用SET NAMES语句设置一次连接字符集即可;

但当使用长连接时,请注意保持连接通畅并在断开重连后用SET NAMES语句显式重置连接字符集。

其他注意事项

• my.cnf中的default_character_set设置只影响mysql命令连接服务器时的连接字符集,不会对使用libmysqlclient库的应用程序产生任何作用!

• 对字段进行的SQL函数操作通常都是以内部操作字符集进行的,不受连接字符集设置的影响。

• SQL语句中的裸字符串会受到连接字符集或introducer设置的影响,对于比较之类的操作可能产生完全不同的结果,需要小心!

MySQL:windows中困扰着我们的中文乱码问题的更多相关文章

  1. 解决ubuntu中zip解压的中文乱码问题

    转自解决ubuntu中zip解压的中文乱码问题 在我的ubuntu12.10中,发现显示中文基本都是正常的,只有在解压windows传过来的zip文件时,才会出现乱码.所以,我用另一个方法解决中文乱码 ...

  2. 尚硅谷面试第一季-09SpringMVC中如何解决POST请求中文乱码问题GET的又如何处理呢

    目录结构: 关键代码: web.xml <filter> <filter-name>CharacterEncodingFilter</filter-name> &l ...

  3. python基础系列教程——Python中的编码问题,中文乱码问题

    python基础系列教程——Python中的编码问题,中文乱码问题 如果不声明编码,则中文会报错,即使是注释也会报错. # -*- coding: UTF-8 -*- 或者 #coding=utf-8 ...

  4. 一句python,一句R︱python中的字符串操作、中文乱码、NaN情况

    一句python,一句R︱python中的字符串操作.中文乱码.NaN情况 先学了R,最近刚刚上手Python,所以想着将python和R结合起来互相对比来更好理解python.最好就是一句pytho ...

  5. 解决“在UBUNTU下打开windows中创建的文本文件,中文显示乱码”的问题 。

    在UBUNTU下打开windows中用notepad等工具创建的txt或程序源码等文本文件,中文显示乱码,原因是windows中的txt文件编码方式为GBK,UBUNTU中为utf-8. 解决办法:在 ...

  6. 解决windows 10英文版操作系统中VS2017控制台程序打印中文乱码问题

    当您在windows 10英文版的操作系统中运行Vs2017控制台应用程序时,程序可能无法正常显示中文,中文都变成了乱码.这是由于大部分中文程序所使用的文字编码与Windows 英文系统的文字编码不同 ...

  7. vc6.0运用mysql数据库中的编码所导致的乱码问题(接收和输出的编码必须要一致)

    [编译中遇见的问题]       ①在用vc 6.0去调用MySQL中的数据时,出现中文乱码       ②不明白mysql中的码制 [开始解决问题]      ①打开mysql控制台         ...

  8. python之MySQL MySQLdb 推荐使用姿势,解决中文乱码

    0.目录 2.setup(1) 安装步骤,可以顺带安装mysql administrator和mysql query browser(2) 安装完毕,修改 my.ini(3) 重启 mysql 服务: ...

  9. 【已解决】关于IDEA中 Tomcat 控制台打印日志中文乱码的解决

    在 Idea 上面使用 Tomcat 时,发现控制台打印信息的时候,出行中文乱码问题; 可以通过以下几种解决办法 1:在-Dfile.encoding=UTF-8 在vm中设置编码方式 2.然后从Fi ...

随机推荐

  1. win10 64位 安装scrapy

    在学习python时,不可避免下载了Anaconda,当我打算写爬虫时,urllib,requests,selenium,pyspider都已经安装好了,可以直接使用了,但是有一天我想要使用scrap ...

  2. Win7 VS2017 Boost Python入门

    闲来无事想练习下用Python作为游戏脚本绑定到C++,网上搜了下,Python文档有些例子,但是太过复杂,gayhub无意中看到有人用Boost Python绑定,简单粗暴,省时省力,记录备忘. 写 ...

  3. Notes : <Hands-on ML with Sklearn & TF> Chapter 6

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  4. 使用 vs code 搭建vue项目(一)

    1. 配置环境 1.1. 安装nodejs,下载地址:https://nodejs.org/en/download/. 步骤-..安装完成后,输入node-v,提示如下,则安装完成. 1.2. 安装v ...

  5. Storm知识点笔记

    Spark和Storm Spark基于MapReduce算法实现的分布式计算,不同于MapReduce的是,作业中间结果可以保存在内存中,而不要再读写HDFS, Spark适用于数据挖掘和机器学习等需 ...

  6. listcard记录

    .listcard-bg{ .listcard-head{ background: #F34A55; width: 100%; height: 50px; margin-bottom: -50px; ...

  7. eclipse 工作区空格和回车键显示为乱码

    eclipse 工作区空格和回车键显示为乱码 解决方法:Windows => Preferences => General =>Editors =>Text Editor =& ...

  8. day24_雷神_django项目部署

    # django项目部署 ... curl -I www.baidu.com 得到响应头信息 vim 里shift + % 找括号的另一半 find / -name virtualenv 3.创建虚拟 ...

  9. 如何用kaldi做孤立词识别三

    这次wer由15%下降到0%了,后面跑更多的模型 LOG (apply-cmvn[5.2.124~1396-70748]:main():apply-cmvn.cc:162) Applied cepst ...

  10. [翻译][架构设计]The Clean Architecture

    原文地址:The Clean Architecture The Clean Architecture Over the last several years we've seen a whole ra ...