接着上一篇继续来一篇关于mysql字符设置等问题学习笔记,这篇就不说什么废话了,直接进入正题,不过仍是感谢十八哥的无私分享!php
咱们首先看看mysql整个数据存储和读取一个流程:mysql
链接器(connection)sql
特性:连接客户端与服务器数据库
过程:windows
客户端的字节先发给链接器,服务器
链接器选择一种编码将其转换,临时存储学习
再次转换成 服务器西药的编码,并正真的存储在服务器上 编码
如今,咱们以mysql这个流程说一下,在存入数据和读取数据时的编码转换。spa
如图翻译
存入数据:
读取数据:
A:client:GBK ---> 链接器接受并转为utf8 ---->数据库服务器和链接器编码相同不用转码直接给服务器
B:client:GBK ---> 不转 ---->链接器--->转码---->数据库服务器存储
C:client:GBK <--->不转 <----链接器<---转码<----数据库服务器存储
以上就是当client和sever编码不一致存储读取时,链接器在其中进行转码的过程。固然,在client和sever编码一致时,链接器就没必要转码,直接发送数据存储就能够了,这里就不作图片说明。
在这个其中就涉及到了client端设置客户端、链接器端、服务器端编码的问题?
咱们可能常用这句命令:set names utf8; 但是其中的具体意义是什么?
咱们首先看看这条命令:show variables like ‘%char%’
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 | D:\phpStudy\MySQL\share\charsets\ | +--------------------------+-----------------------------------+
其中的:
character_set_client 指的就是设置的客户端编码
character_set_connection 指的是链接器设置的编码
character_set_results 返回数据设置的编码(这是在取出数据返回到client时设置的编码)
那么,剩下的都是什么意思?
character_set_database 默认数据库的字符集,不管默认数据库如何改变,都是这个字符集;若是没有默认数据库,那就使用 character_set_server指定的字符集,这个变量建议由系统本身管理,不要人为定义。
character_set_filesystem 把os上文件名转化成此字符集,即把 character_set_client转换character_set_filesystem, 默认binary是不作任何转换的
character_set_server 数据库服务器的默认字符集
character_set_system 这个值老是utf8,不须要设置,是为存储系统元数据的字符集
character_sets_dir 字符集的文件路径
如何设置:
命令是这样的格式: set character_set_client=GBK;
其余的都是类似的,你们类推便可。
那么看了上面的mysql> show variables like '%char%';的设置,咱们想知道:为何有时候我写的中文会乱码,不是一致吗?都是utf8?其实,这是mysql在安装是的一个设置,咱们真正执行:
insert into test values(1,’趴在巨人肩上的矮子’)的时候,一切都觉得是UTF8,可是真的就是嘛?
咱们的windows在中国,系统用的是GBK编码,其实咱们输入的这几个汉字就是GBK编码的,mysql的整个流程却都是UTF8,这就固然就乱码了,咱们能够看看咱们的client编码:
如图:
因此,咱们就必须设置,让数据库知道,客户端此时要输入的是GBK,这时就能够设置
set character_set_client=GBK;
固然,你是要 set names GBK; 咱们来看看这条命令的结果,你们就明白了
mysql> set names gbk;
Query OK, 0 rows affected (0.03 sec) mysql> show variables like '%char%'; +--------------------------+-----------------------------------+ | Variable_name | Value | +--------------------------+-----------------------------------+ | character_set_client | gbk | | character_set_connection | gbk | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | gbk | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | D:\phpStudy\MySQL\share\charsets\ | +--------------------------+-----------------------------------+ 8 rows in set (0.00 sec)
咱们看到character_set_client 、character_set_connection 、character_set_results 都已经设置成了GBK,那就说明:此时链接器、客户端和返回结果都是GBK,那么,插入数据时,就是咱们上面流图的第二种状况:
B:client:GBK ---> 不转 ---->链接器--->转码---->数据库服务器存储
同时,当你须要查看结果时,也不会乱码,由于character_set_results已是GBK了。这下清楚了吧!
固然,咱们设置set character_set_results=GBK;这样只能保证咱们select操做时获得的汉字数据不会乱码,若是没有设置character_set_client,咱们的insert照样也会乱码,并且,咱们仔细考虑:当你没有设置character_set_client时,你的GBK汉字mysql以utf8存了,此时会怎样?
mysql> show variables like '%char%'; +--------------------------+-----------------------------------+ | Variable_name | Value | +--------------------------+-----------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | gbk | | character_set_filesystem | binary | | character_set_results | gbk | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | D:\phpStudy\MySQL\share\charsets\ | +--------------------------+-----------------------------------+ 8 rows in set (0.00 sec) mysql> insert into tb_1 values(6,'来了','男','百度',999,11); Query OK, 1 row affected, 3 warnings (0.03 sec) mysql> select * from tb_1; +----+------+--------+----------+---------+-------+ | id | name | gender | company | salary | fanbu | +----+------+--------+----------+---------+-------+ | 6 | | | | 999.00 | 11 | | 2 | 李四 | 女 | 腾讯 | 6524.50 | 1000 | | 3 | 王五 | 男 | 新浪 | 5000.00 | 520 | | 4 | 赵六 | 女 | 阿里巴巴 | 5600.00 | 300 | | 5 | 刘思 | 女 | 支付宝 | 3000.00 | 200 | +----+------+--------+----------+---------+-------+ 5 rows in set (0.00 sec) mysql> set character_set_client=gbk; Query OK, 0 rows affected (0.00 sec) mysql> select * from tb_1; +----+------+--------+----------+---------+-------+ | id | name | gender | company | salary | fanbu | +----+------+--------+----------+---------+-------+ | 6 | | | | 999.00 | 11 | | 2 | 李四 | 女 | 腾讯 | 6524.50 | 1000 | | 3 | 王五 | 男 | 新浪 | 5000.00 | 520 | | 4 | 赵六 | 女 | 阿里巴巴 | 5600.00 | 300 | | 5 | 刘思 | 女 | 支付宝 | 3000.00 | 200 | +----+------+--------+----------+---------+-------+ 5 rows in set (0.00 sec)
能够看到,字节丢失了,咱们输入的信息不见了,怎么理解?
GBK汉字mysql以utf8存了,可是咱们已经设置显示结果是GBK,按理来讲,utf8的乱码,翻译过来仍是GBK的正确啊?
就像这样:
假如:王 二进制GBK:0001 –> 存储UTF8 0010
取出时:UTF8 0010 -> GBK 0001
不该该不对啊?
实际上是这样的:
假如:王 二进制GBK:0001 –> character_set_client没有设置,mysql觉得这个0001是UTF8的因此这里存储UTF8 0001 而0001的UTF8对应是个:李,
取出时:UTF8 0001(李) -> character_set_results=GBK –>将UTF8的 0001转为了GBK的0110了,此时GBK也不知道这是个什么东西了,GBK没有这个字符,因此没法显示
注意
可是很不幸,mysql自带的客户端,这些set names gbk;等命令的设置都只是临时的!!
当咱们,关闭client,从新打开时,咱们会发现又乱了,又要从新设置,哎!因此每次使用必定首先设置好这个东西,对于怎样不用这么麻烦?我没有深刻的去研究,可是当你肯定你不少时候用的是GBK编码或者其余编码时,那么就在安装mysql时注意设置
好了,就这么多吧,这些笔记,不光只是抄写,也是加入了一些之前本身的认识和验证的猜测,总的感受就是:此次算是基本弄明白了,这些编码是怎么一回事了。
若是有什么错误和不明白的地方,亲你们留言,谢谢!睡觉喽,吼吼、、、、、