MySQL 乱码之我见
先着重介绍一下mysql的字符集,这样能对产生mysql的根源有一个了解。mysql 的字符集支持有两个方面:字符集(Character set)和排序方式(Collation)。另外对于字符集的支持细化到四个层次: 服务器(server),数据库(database),数据表(table)和连接(connection)。
连上mysql 后使用status 命令,可以看到类似如下输出:
>mysql statusConnection id: 305Current database:Current user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: utf8Client characterset: utf8Conn. characterset: utf8
Server characterset 就是mysql默认字符集,当创建数据库没有指定字符集时数据库就采用此默认值。可以在mysql的配置文件中的 mysqld 段中对此值进行修改
[mysqld]port = 3306socket = /tmp/mysql.sockcharacter-set-server = utf8collation-server = utf8_general_ci
Db characterset:是当前数据库默认的字符集,当创建表时没有指定字符集,此表就使用当前默认值。例如创建一个 db_test 数据库,字符集使用 latin1
CREATE DATABASE `db_test` CHARACTER SET ‘latin1‘ COLLATE ‘latin1_swedish_ci‘;use db_test;
然后再使用 status 命令,可以看到这个时候 Db characterset 变为 latin1 了
>mysql statusConnection id: 305Current database: db_testCurrent user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: latin1Client characterset: utf8Conn. characterset: utf8
在数据库中分别创建两种表 test1 和 test2,其中 test1 使用默认字符集, test2 指定字符集为GBK
create table test1 (name varchar(20));create table test2 (name varchar(20)) default charset=GBK;
使用 show create table 命令查看上述两张表,可以看到 test1 使用了当前数据库的默认字符集latin1,而test2使用的字符集是GBK。
mysql> show create table test1;+-------+-------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+-------------------------------------------------------------------------------------------------+| test1 | CREATE TABLE `test1` ( `name` varchar(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 |+-------+-------------------------------------------------------------------------------------------------+mysql> show create table test2;+-------+----------------------------------------------------------------------------------------------+| Table | Create Table |+-------+----------------------------------------------------------------------------------------------+| test2 | CREATE TABLE `test2` ( `name` varchar(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=gbk |+-------+----------------------------------------------------------------------------------------------+
mysql 存储信息最终是已二进制的形式来存储的。所以在存储之前就需要对信息进行编码,同时从数据库读取信息后需要解码。具体使用那种编码、解码方式就是根据Client characterset以及表对应的字符集,如果没有显示的指定,那么会有一个默认值。当使用命令行的方式连接mysql,可以在mysql 配置中 mysql 段来指定默认Client characterset。例如:
[client]port = 3306socket = /tmp/mysql.sockdefault-character-set = utf8
也可以使用在连接时候指定
mysql -uroot -p --default-character-set=utf8
另外在登录mysql 后也可以使用 set names 来指定
set names utf8
关于优先级,set names utf8 最高,mysql -uroot -p --default-character-set=utf8 其次、my.cnf 最后。
上面对字符集做了一个简单的介绍,建议大家也把上面的mysql 命令试一下,这样理解或更加深刻。现在再来说一下乱码的情况,一般出现乱码就是因为字符集(编码)不同,换句话说就是当字符集(编码)一致时就不会出现乱码。前面介绍了一下字符集,所以知道了好几种,那到底是需要什么字符集一致呢?答案是:Client characterset 与 数据库表的字符集。 下面还是通过例子来说明,使用上面创建的表 test1。
由于test1使用的字符集是 latin1,那么使用下面的方式连上mysql
mysql -uroot -p db_test --default-character-set=latin1
再次确认一下Client characterset 与 数据库表的字符集
mysql> status--------------mysql Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using EditLine wrapperConnection id: 310Current database: db_testCurrent user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: latin1Client characterset: latin1Conn. characterset: latin1-------------------------mysql> show create table test1;+-------+-------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+-------------------------------------------------------------------------------------------------+| test1 | CREATE TABLE `test1` ( `name` varchar(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 |+-------+-------------------------------------------------------------------------------------------------+
可以看到Client characterset与表的字符集是一致的,然后插入一条含有中文的记录,同时查询看看。
mysql> insert into test1(name) values(‘中test文1234测试‘);mysql> select * from test1;+----------------------+| name |+----------------------+| 中test文1234测试 |+----------------------+
现在证明当Client characterset与表的字符集一致时,没有出现乱码。那现在使用set names 来修改一下 Client characterset 看看效果。
mysql> set names utf8;Query OK, 0 rows affected (0.00 sec)mysql> status--------------mysql Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using EditLine wrapperConnection id: 310Current database: db_testCurrent user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: latin1Client characterset: utf8Conn. characterset: utf8mysql> select * from test1;+--------------------------------------+| name |+--------------------------------------+| ??-test?–?1234?μ?èˉ? |+--------------------------------------+
utf8 出现乱码,再试试gbk
mysql> set names gbk;Query OK, 0 rows affected (0.00 sec)mysql> status--------------mysql Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using EditLine wrapperConnection id: 310Current database: db_testCurrent user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: latin1Client characterset: gbkConn. characterset: gbkmysql> select * from test1;+------------------------+| name |+------------------------+| ???test?1234???? |+------------------------+
上面把Client characterset 设置分别设置为 utf8 或 GBK 后,然后查询都出现了乱码,而且乱码显示还不一样。下面再测试一样不同Client characterset字符集先插入在读取的情况。
mysql -uroot -p db_test --default-character-set=utf8 mysql> status--------------mysql Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using EditLine wrapperConnection id: 312Current database: db_testCurrent user: root@localhostSSL: Not in useCurrent pager: stdoutUsing outfile: ‘‘Using delimiter: ;Server version: 5.6.23 MySQL Community Server (GPL)Protocol version: 10Connection: Localhost via UNIX socketServer characterset: utf8Db characterset: latin1Client characterset: utf8Conn. characterset: utf8mysql> truncate table test1;Query OK, 0 rows affected (0.01 sec)mysql> select * from test1;Empty set (0.00 sec)mysql> insert into test1(name) values(‘中test文1234测试‘); Query OK, 1 row affected, 1 warning (0.00 sec)mysql> select * from test1;+--------------+| name |+--------------+| ?test?1234?? |+--------------+
上面的例子说明当字符集不一致出现乱码了。 如果再把Client characterset 修改为和数据库表一致,然后看看刚刚插入的记录是否还是显示乱码
mysql> set names latin1;Query OK, 0 rows affected (0.00 sec)mysql> select * from test1;+--------------+| name |+--------------+| ?test?1234?? |+--------------+1 row in set (0.00 sec)
还是乱码,也就是通过字符集设置也无法把乱码还原了。
通过上面这些例子可以得出结论,只有当Client characterset与表的字符集一致才不会出现乱码。
MySQL 乱码之我见
标签:
小编还为您整理了以下内容,可能对您也有帮助:
MySQL乱码的几种原因
MySQL之所以会乱码,无非是以下几种原因: 1、存进数据库之前就乱码 2、在存进数据库过程中乱码 3、存进数据库后乱码 想知道在哪
MySQL之所以会乱码,无非是以下几种原因:
1、存进数据库之前就乱码
2、在存进数据库过程中乱码
3、存进数据库后乱码
想知道在哪里出现乱码很简单,在后台打印一下就知道了。
既然知道问题出在哪里,那解决方法也很简单:
1、jsp设置编码是utf-8,保证传到后台的是utf-8的编码
2、在数据库连接上加这么一段jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8,保证传输过程是utf-8的。
3、设置数据库的编码为utf-8,在my.ini设置或者在Config设置也行,,注意的是my.ini里default-character-set要改两处地方
4、url或者easyui乱码,可以试一下将tomcat的server.xml中的
改为
要保证不乱码,首先要做到编码要统一,其他问题都好找出来。完。
本文永久更新链接地址:
关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)
最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅。
首先:
用show variables like “%colla%”;show varables like “%char%”;这两条命令查看数据库与服务端的字符集设置
如果查看出来都是gbk2312,或 gbk,那么就只能支持简体中文,繁体和一些特殊符号是不能插入的,我们只有修改字符集为UTF-8,
修改方法如下:
用记事本或UitraEdit打开mysql数据库安装目录下的my.ini文件打开, 然后Ctrl+F搜索default-character-set,将后面的字符集修改为UTF8,注意要修改两个地方,一个事客户端的,一个是服务端的。
然后保存,重启mysql服务、、进去继续用show variables like “%colla%”;show varables like “%char%”;着两条语句查询一下字符集。 如图:
到此就配置完成了。
注意:
如果以前建有数据库没有删除的 请用 show database 数据库名;和 show create table 表名;查看一下数据库和表的字符集是否为UTF8 , 因为修改my.ini文件,它不能修改原来数据库的的字符集。在命令行下面可以用
alter database 数据库名 character set “字符集”; 命令来修改数据库字符集
还有一点要注意的是,修改为UTF8以后,在命令行下面中文是乱码的,只输出到页面或控制台是正常的,这个问题我也上网查了一下,貌似命令行下面不支持UTF8,我也不太清楚。
当修改以后,在命令行下面如果要插入中文,可以在插入语句之前执行,set names gbk2312;就可以插入中文了,但是不能插入繁体和一些特殊符号。
关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)
最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅。
首先:
用show variables like “%colla%”;show varables like “%char%”;这两条命令查看数据库与服务端的字符集设置
如果查看出来都是gbk2312,或 gbk,那么就只能支持简体中文,繁体和一些特殊符号是不能插入的,我们只有修改字符集为UTF-8,
修改方法如下:
用记事本或UitraEdit打开mysql数据库安装目录下的my.ini文件打开, 然后Ctrl+F搜索default-character-set,将后面的字符集修改为UTF8,注意要修改两个地方,一个事客户端的,一个是服务端的。
然后保存,重启mysql服务、、进去继续用show variables like “%colla%”;show varables like “%char%”;着两条语句查询一下字符集。 如图:
到此就配置完成了。
注意:
如果以前建有数据库没有删除的 请用 show database 数据库名;和 show create table 表名;查看一下数据库和表的字符集是否为UTF8 , 因为修改my.ini文件,它不能修改原来数据库的的字符集。在命令行下面可以用
alter database 数据库名 character set “字符集”; 命令来修改数据库字符集
还有一点要注意的是,修改为UTF8以后,在命令行下面中文是乱码的,只输出到页面或控制台是正常的,这个问题我也上网查了一下,貌似命令行下面不支持UTF8,我也不太清楚。
当修改以后,在命令行下面如果要插入中文,可以在插入语句之前执行,set names gbk2312;就可以插入中文了,但是不能插入繁体和一些特殊符号。
如何解决MySQL字符集乱码问题
一、转码失败
在数据写入到表的过程中转码失败,数据库端也没有进行恰当的处理,导致存放在表里的数据乱码。
针对这种情况,前几篇文章介绍过客户端发送请求到服务端。
其中任意一个编码不一致,都会导致表里的数据存入不正确的编码而产生乱码。
比如下面简单一条语句:
set @a = "文本字符串";
insert into t1 values(@a);
1. 变量 @a 的字符编码是由参数 CHARACTER_SET_CLIENT 决定的,假设此时编码为 A,也就是变量 @a 的编码。
2. 写入语句在发送到 MySQL 服务端之前的编码由 CHARACTER_SET_CONNECTION 决定,假设此时编码为 B。
3. 经过 MySQL 一系列词法,语法解析等处理后,写入到表 t1,表 t1 的编码为 C。
那这里编码 A、编码 B、编码 C 如果不兼容,写入的数据就直接乱码。
二、客户端乱码
表数据正常,但是客户端展示后出现乱码。
这一类场景,指的是从 MySQL 表里拿数据出来返回到客户端,MySQL 里的数据本身没有问题。客户端发送请求到 MySQL,表的编码为 D,从 MySQL 拿到记录结果传输到客户端,此时记录编码为 E(CHARACTER_SET_RESULTS)。
那以上编码 E 和 D 如果不兼容,检索出来的数据就看起来乱码了。但是由于数据本身没有被破坏,所以换个兼容的编码就可以获取正确的结果。
这一类又分为以下三个不同的小类:
1)字段编码和表一致,客户端是不同的编码
比如下面例子, 表数据的编码是 utf8mb4,而 SESSION 1 发起的连接编码为 gbk。那由于编码不兼容,检索出来的数据肯定为乱码。
2)表编码和客户端的编码一致,但是记录之间编码存在不一致的情形
比如表编码是 utf8mb4,应用端编码也是 utf8mb4,但是表里的数据可能一半编码是 utf8mb4,另外一半是 gbk。那么此时表的数据也是正常的,不过此时采用哪种编码都读不到所有完整的数据。这样数据产生的原因很多,比如其中一种可能性就是表编码多次变更而且每次变更不彻底导致(变更不彻底,我之前的篇章里有介绍)。举个例子,表 t3 的编码之前是 utf8mb4,现在是 gbk,而且两次编码期间都被写入了正常的数据。
3)每个字段的编码不一致,导致乱码
和第二点一样的场景。不同的是:非记录间的编码不统一,而是每个字段编码不统一。举个例子,表 c1 字段 a1,a2。a1 编码 gbk,a2 编码是 utf8mb4。那每个字段单独读出来数据是完整的,但是所有字段一起读出来,数据总会有一部分乱码。
三、LATIN1
还有一种情形就是以 LATIN1 的编码存储数据
估计大家都知道字符集 LATIN1,LATIN1 对所有字符都是单字节流处理,遇到不能处理的字节流,保持原样,那么在以上两种存入和检索的过程中都能保证数据一致,所以 MySQL 长期以来默认的编码都是 LATIN1。这种情形,看起来也没啥不对的点,数据也没乱码,那为什么还有选用其他的编码呢?原因就是对字符存储的字节数不一样,比如 emoji 字符 "❤",如果用 utf8mb4 存储,占用 3 个字节,那 varchar(12) 就能存放 12 个字符,但是换成 LATIN1,只能存 4 个字符。
总结
通过上面的详细说明,相信对 MySQL 乱码问题已经有一个很好的了解了。那来回顾下本篇的内容。本篇主要列列举了 MySQL 乱码可能出现的场景,并对应给出详细的处理方法以及相关建议,希望以后大家永远不会出现乱码问题。
使用MySQL导入数据时出现乱码的两种解决方法
使用MySQL导入数据时出现乱码的两种解决方法如下:1、添加 –default-character-set
先检查一下,目标数据编码。 56云 分享
使用目标库编码导入数据,如下:
2、修改数据库编码
此教程方法必须谨慎使用,需初始化数据库或将企业数据库技术可以覆盖情况下使用,否则导致数据库出现乱码