共计 4589 个字符,预计需要花费 12 分钟才能阅读完成。
丸趣 TV 小编给大家分享一下 Linux 下 mysql 字符集问题如何处理,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
4.1 之前的 MySQL 不支持多语言,所以它会将你给它的数据“原封不动”地保存,再“原封不动”地读出来。4.1 及以后的版本开始支持多语言,这个所谓的多语言,就是在输入输出时 MySQL 会替你做编码转换。而这个转换规则就是由客户端编码和服务器端编码来决定的。编码转换的规则就是,在输入数据时将编码由“客户端编码”转换为“服务器端编码”,输出时将数据由“服务器端编码”转换为“客户端编码”。
MySQL 4.1.x 开始支持以下这些事情
使用多种字符集 (Character Set) 来存储字符
使用多种校对规则 (Collation) 来比较字符串
在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合字符串
允许定义任何级别的字符集和校对规则
MySQL 4.1 及以上版本的字符集支持 (Character Set Support) 有两个方面:字符集 (Character Set) 和校对规则 (Collation)。字符集和校对规则有 4 个级别的默认设置:服务器(server),数据库(database),数据表(table) 和连接(connection)。
MySQL 字符集设置
character_set_server:默认的内部操作字符集
character_set_database:当前选中数据库的默认字符集
vi /etc/my.cnf– 全局选项
[mysqld]
default-character-set=utf8
只能改变对存储层(server,database,table,column,system)的设定,对于客户端和服务器端的通讯层没有任何影响
character_set_client:客户端来源数据使用的字符集
character_set_connection:连接层字符集
character_set_results:查询结果字符集
vi /etc/my.cnf– 全局选项
[mysql]
default-character-set=utf8
修改当前 session 值:
SET NAMES x 语句与这三个语句等价:
mysql SET character_set_client = x;
mysql SET character_set_results = x;
mysql SET character_set_connection = x;
character_set_system:系统元数据 (字段名等) 字符集
还有以 collation_开头的同上面对应的变量,用来描述字符序。
或者:
CREATE DATABASE db_name DEFAULT CHARACTER SET charset_name;
ALTER DATABASE db_nameDEFAULT CHARACTER SET charset_name;
MySQL 中的字符集转换过程
1. MySQL Server 收到请求时将请求数据从 character_set_client 转换为 character_set_connection;
2. 进行内部操作前将请求数据从 character_set_connection 转换为内部操作字符集,其确定方法如下:
使用每个数据字段的 CHARACTER SET 设定值;
若上述值不存在,则使用对应数据表的 DEFAULT CHARACTER SET 设定值(MySQL 扩展,非 SQL 标准);
若上述值不存在,则使用对应数据库的 DEFAULT CHARACTER SET 设定值;
若上述值不存在,则使用 character_set_server 设定值。
3. 将操作结果从内部操作字符集转换为 character_set_results。
检测字符集问题的一些手段
SHOW CHARACTER SET;
SHOW COLLATION;
SHOW VARIABLES LIKE‘character%’;
SHOW VARIABLES LIKE‘collation%’;
SQL 函数 HEX、LENGTH、CHAR_LENGTH
SQL 函数 CHARSET、COLLATION
STATUS;
常见问题解析
向默认字符集为 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)符号,以后查询时不管连接字符集设置如何都无法恢复其内容了。
本次两次测试内容:
环境 ed Hat Enterprise Linux Server release 5.5 (Tikanga)LANG=zh_CN.UTF-8
mysql5.0.77
测试一:
Vi/etc/my.cnf
[mysqld]
default-character-set=utf8
mysql show variables like char%
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | lantin1 |
| character_set_connection | lantin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | lantin1 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/
结果:服务器端正常,
在客户端访问 WindowXp EMS SQL Manager for my sql 是乱码:
测试二:
set names utf8;
mysql show variables like char%
+————————–+—————————-+
| 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 | /usr/share/mysql/charsets/
测试一中的数据变为乱码,测试二中的数据正常显示。
测试二的数据在客户端数据也正常显示。
如果从客户端插入数据:测试三
在服务器则显示乱码:
测试三:
set names utf8;
set character_set_results=gb2312
insert into test values(测试
客户端正常,服务器乱码
客户端:
处理乱码的思路:
让服务器端和客户端的字符集保持一致。
服务器端的编码是由字符集 (Character Set) 和校对规则 (Collation) 决定的。
上面提到,MySQL 中是根据下面几个变量确定服务器端和客户端用的什么字符集:
character_set_client 客户端字符集
character_set_connection 客户端与服务器端连接采用的字符集
character_set_results SELECT 查询返回数据的字符集
character_set_database 数据库采用的字符集
也就是说,只要保证这几个变量采用一致的字符集,就不会出现乱码问题了。
很多情况下,这样设置了之后就能把乱码问题解决了。但是还是不能完全避免出现乱码的可能,为什么呢? 因为 character_set_client,character_set_connection 这两个变量仅用于保证与 character_set_database 编码的一致,而 character_set_results 则用于保证 SELECT 返回的结果与程序的编码一致。例如,你的数据库 (character_set_database) 用的是 utf8 的字符集,那么你就要保证 character_set_client,character_set_connection 也是 utf8 的字符集。而你的程序也许采用的并不是 utf8,比如你的程序用的是 gbk,那么你若把 character_set_results 也设置为 utf8 的话就会出现乱码问题。此时你应该把 character_set_results 设置为 gbk。这样就能保证数据库返回的结果与你的程序的编码一致。
备注:
1、要保证数据库中存的数据与数据库编码一致,即数据编码与 character_set_database 一致;
2、要保证通讯的字符集与数据库的字符集一致,即 character_set_client, character_set_connection 与 character_set_database 一致;
3、要保证 SELECT 的返回与程序的编码一致,即 character_set_results 与程序编码一致;
4、要保证程序编码与浏览器编码一致,即程序编码与 / 一致。
更改设定值的一个方法是通过重新编译。如果希望在从源程序构建时更改默认服务器字符集和校对规则,使用:–with-charset 和 –with-collation 作为 configure 的参量。例如:
shell ./configure –with-charset=latin1
以上是“Linux 下 mysql 字符集问题如何处理”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!