MySQL字符集乱码

您所在的位置:网站首页 mysql获取某字符 MySQL字符集乱码

MySQL字符集乱码

2023-04-11 17:47| 来源: 网络整理| 查看: 265

什么是字符集?

    字符集是一套符号和编码的规则,可以想象为二进制位和符号的转换表。

MySQL支持的字符集

    MySQL数据库可以支持多种字符集。

    MySQL字符集包括字符集(character set)和校对规则(collation)两个概念。字符集是用来定义MySQL存储字符串的方式,校对规则则是用来定义了比较字符串的方式。字符集和校对规则是一对多的关系。

    每个字符集至少对应一个校对规则。

# 查看支持的字符集 mysql> SHOW CHARACTER SET; # 查看支持的校对规则 mysql> SHOW COLLATION;

    MySQL字符集设置非常灵活,分别可以在服务器级、数据库级、表级、字段级设置。

数据库对象的字符集的指定有如下继承关系:

Server -> Database -> Table -> Column

也就是说,如果某一级没有显示指定字符集,那么将继承上一级的字符集。

# 查看服务器字符集相关的系统变量 mysql> SHOW VARIABLES LIKE ‘%char%‘;

乱码问题?

MySQL处理连接时,外部连接发送过来的SQL请求会根据以下顺序进行转换:character_set_client           //客户连接所采用的字符集|character_set_connection  //MySQL连接字符集|character_set_database    //数据库所采用的字符集(表,列)|character_set_results        //返回的结果所采用的字符集

我们告诉服务器,我发送给你的数据是什么编码? character_set_client

如果发现和连接器指定的编码不一致,要转换为什么编码? character_set_connection

查询的结果用什么编码? character_set_results

如果以上三者都为字符集N,可简写为: set names N;

下面通过实例来演示为什么会乱码?

# 创建一个表 mysql> CREATE TABLE person (     -> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,     -> name VARCHAR(30)     -> ) DEFAULT CHARSET utf8; # 然后执行下面3条命令, 可以简写为 set names utf8; set character_set_client=utf8; set character_set_cOnnection=utf8; set_character_set_results=utf8; # 查看当前字符集设置 mysql> show variables like ‘%char%‘; +--------------------------+----------------------------+ | Variable_name            | Value                      | +--------------------------+----------------------------+ | character_set_client     | utf8                       | | character_set_connection | utf8                       | | character_set_database   | latin1                     | | character_set_filesystem | binary                     | | character_set_results    | utf8                       | | character_set_server     | latin1                     | | character_set_system     | utf8                       | | character_sets_dir       | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ # 然后插入一条数据 mysql> INSERT INTO person(name) VALUES(‘中文‘); # 查询 mysql> SELECT * FROM person; +----+--------+ | id | name   | +----+--------+ |  1 | 中文   | +----+--------+ # 显示结果是正常的。 # 好,接下来,我们改变character_set_results 为 gbk mysql> set character_set_results=gbk; Query OK, 0 rows affected (0.04 sec) mysql> SELECT * FROM person; +----+------+ | id | name | +----+------+ |  1 |      | +----+------+

产生乱码的根本原因就是:

各字符集系统变量不一致,导致进行字符集转换。

    比如说:客户机没有正确地设置client字符集,导致原先的SQL语句被转换成connection 所指字符集,而这种转换,可能是会丢失信息的,如果client是utf8格式,那么如果转换成gb2312格式,这其中必定会丢失信息,反之则不会丢失。一 定要保证connection的字符集大于client字符集才能保证转换不丢失信息。同理,connection与results也是这样。就像编程语言中的数据类型相互转换时一样,比如把double类型强制转换成int类型,就会造成精度的丢失一样。

    我们来仔细说明一下转换的过程:

向默认字符集为utf8的数据表插入utf8编码的数据前没有设置连接字符集,查询时设置连接字符集为utf8     – 插入时根据MySQL服务器的默认设置,character_set_client、character_set_connection和character_set_results均为latin1;     – 插入操作的数据将经过latin1=>latin1=>utf8的字符集转换过程,这一过程中每个插入的汉字都会从原始的3个字节变成6个字节保存;     – 查询时的结果将经过utf8=>utf8的字符集转换过程,将保存的6个字节原封不动返回,产生乱码。

向默认字符集为latin1的数据表插入utf8编码的数据前设置了连接字符集为utf8     – 插入时根据连接字符集设置,character_set_client、character_set_connection和character_set_results均为utf8;     --插入数据将经过utf8=>utf8=>latin1的字符集转换,若原始数据中含有\u0000~\u00ff范围以外的 Unicode字符,会因为无法在latin1字符集中表示而被转换为“?”(0×3F)符号,以后查询时不管连接字符集设置如何都无法恢复其内容了。

综上,终极解决方案如下:1.首先要明确你的客户端时候何种编码格式,这是最重要的(IE6一般用utf8,命令行一般是gbk,一般程序是gb2312)2.确保你的数据库使用utf8格式,很简单,所有编码通吃。3.一定要保证connection字符集大于等于client字符集,不然就会信息丢失,比如: latin1 ,若设置set character_set_client = gb2312,那么至少connection的字符集要大于等于gb2312,否则就会丢失信息4. 以上三步做正确的话,那么所有中文都被正确地转换成utf8格式存储进了数据库,为了适应不同的浏览器,不同的客户端,你可以修改 character_set_results来以不同的编码显示中文字体,由于utf8是大方向,因此web应用是我还是倾向于使用utf8格式显示中文 的。

总结    根据上面的分析和建议,我们解决我们遇到问题应该使用什么方法大家心里应该比较清楚了。对,就是在创建database的时候指定字符集,不要去通过修改默认配置来达到目的,当然你也可以采用指定表的字符集的形式,但很容易出现遗漏,特别是在很多人都参与设计的时候,更容易纰漏。

http://www.cnblogs.com/zzwlovegfj/archive/2012/06/25/2560649.html

http://www.cnblogs.com/discuss/articles/1862248.html

本文出自 “Share your knowledge” 博客,请务必保留此出处http://skypegnu1.blog.51cto.com/8991766/1591215

MySQL字符集乱码



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3