MySQL:windows中困扰着咱们的中文乱码问题

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

  话很少说,直接上图python

  这个东西困扰了我很久,致使我如今对windows映像很是很差,因此就想改为Linux,行了,牢骚就发到这里,直接说问题,明眼人一眼就看出来是编码问题,可是,很少说,继续上图mysql

  明明都设置成了utf8了,但是仍是出现了乱码问题。不是说为了不全部乱码问题,应该采用UTF-8,未来要支持国际化也很是方便,但是为何还出现这个问题。sql

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

    UTF- 8:Unicode Transformation Format-8bit,
容许含BOM,但一般不含BOM。是用以解决国际上字符的一种多字节编码,它对
英文使用8位(即一个字节),中文使用24位(三个字节)来编码。UTF-8包含全
世界全部国家须要用到的字符,是国际编码,通用性强。UTF-8编码的文字能够在
各国支持UTF8字符集的浏览器上显示。如,若是是UTF8编码,则在外国人的英文
IE上也能显示中文,他们无需下载IE的中文语言支持包。

    GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。
GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,
为了区分中文,将其最高位都设定成1。GBK包含所有中文字符,是国家编码,通
用性比UTF8差,不过UTF8占用的数据库比GBK大。

  三者之间的转化

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

GBK、GB2312--Unicode--UTF8

UTF8--Unicode--GBK、GB2312 

  对于一个网站、论坛来讲,若是英文字符较多,则建议使用UTF-8节省空间。不过如今不少论坛的插件通常只支持GBK。windows

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

gb2312是简体中文的码

gbk支持简体中文及繁体中文

big5支持繁体中文

utf-8支持几乎全部字符

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

  咱们在mysql中输入下面命令:服务器

mysql> show variables like '%char%';

  结果:session

+--------------------------+---------------------------------------------------------+
| Variable_name            | Value                                                   |
+--------------------------+---------------------------------------------------------+
| character_set_client     | utf8                                                    |
| character_set_connection | utf8                                                    |
| character_set_database   | utf8                                                    |
| character_set_filesystem | binary                                                  |
| character_set_results    | utf8                                                    |
| character_set_server     | utf8                                                    |
| character_set_system     | utf8                                                    |
| character_sets_dir       | C:\Program Files\MySQL\MySQL Server 5.5\share\charsets\ |
+--------------------------+---------------------------------------------------------+
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 写入中文数据时,在客户端、数据库链接、写入数据库时分别要进行编码转换。在执行查询时,在返回结果、数据库链接、客户端分别进行编码转换。如今咱们应该清楚,乱码发生在数据库、客户端、查询结果以及数据库链接这其中一个或多个环节。

 举个例子:

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

  

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

character-set-server/default-character-set:服务器字符集,默认状况下所采用的。

character-set-database:数据库字符集。

character-set-table:数据库表字符集。

 

  优先级依次增长。因此通常状况下只须要设置character-set-server,而在建立数据库和表时不特别指定字符集,这样统一采用character-set-server字符集。

character-set-client:客户端的字符集。客户端默认字符集。
当客户端向服务器发送请求时,请求以该字符集进行编码。

character-set-results:结果字符集。服务器向客户端返回结果或者信息时,结果以该字符集进行编码。

  
  在客户端,若是没有定义character-set-results,则采用character-set-client字符集做为默认的字符集。因此只须要设置character-set-client字符集。

  要处理中文,则能够将character-set-server和character-set-client均设置为GB2312,若是要同时处理多国语言,则设置为UTF8。

• 系统变量:
– character_set_server:默认的内部操做字符集

– character_set_client:客户端来源数据使用的字符集

– character_set_connection:链接层字符集

– character_set_results:查询结果字符集

– character_set_database:当前选中数据库的默认字符集

– character_set_system:系统元数据(字段名等)字符集

  

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

character_set_client:客户端的字符集。

character_set_results:结果字符集。

character_set_connection:链接字符集。

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

set names gb2312

set character_set_client = 字符集

set character_set_connection = 字符集

set character_set_results = 字符集

 

五,设置MySQL的字符编码

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

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

5.1 基于session会话层

1.首先链接到MySQL :

mysql -uroot -proot

  

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

  

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

  输入:

show variables like '%char%';

  

    

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

  create database test1;
  show create database test1;

  

  

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

  这里将utf-8设置为gbk:

  set character_set_database=gbk;
  set character_set_server=gbk;
    show variables like '%char%';

  

  

咱们发现database和server都变成了gbk,而后咱们再从新建立一个数据库,查看其编码,

  create dabase test2;
  show create dabase test2;

  

    

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

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

   

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

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

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

  set global character_set_database=gbk;
  set global character_ser_server=gbk;
  show variables like '%char%';

  

   

  咱们发现数据库的编码没有修改为功,仍是原来的utf-8。可是当咱们从新建立数据库或者从新建立表的时候,编码就会是咱们所指望的gbk了。

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

  create database test3;
  show variables like '%char%';

  

   

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

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

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

  编辑 /etc/my.cnf,

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

    [mysqld]
    character-set-server=utf8 
    [client]
    default-character-set=utf8 
    [mysql]
    default-character-set=utf8

  

  而后重启数据库便可,service mysql restart.

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

5.3 一劳用逸

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

 

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

 

  这时只须要将下的默认编码 default-character-set=utf8 改成 default-character-set=gbk ,从新启动 MySQL 服务便可。

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
[client]
default-character-set=gbk
[mysql]
default-character-set=gbk

  修改以后,直接上图:

 

 

 5.4  修改数据库字符编码

mysql> alter database mydb character set utf8 ;

  

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

SHOW CHARACTER SET;

• SHOW COLLATION;

• SHOW VARIABLES LIKE ‘character%’;

• SHOW VARIABLES LIKE ‘collation%’;

• SQL函数HEX、LENGTH、CHAR_LENGTH

• SQL函数CHARSET、COLLATION

  

使用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设置的影响,对于比较之类的操做可能产生彻底不一样的结果,须要当心!

相关文章
相关标签/搜索