接着上一篇继续来一篇关于mysql字符设置等问题学习笔记,这篇就不说什么废话了,直接进入正题,不过还是感谢十八哥的无私分享!

  我们首先看看mysql整个数据存储和读取一个流程:

    

  

  连接器(connection)

特性:链接客户端与服务器

过程:

     客户端的字节先发给连接器,

    连接器选择一种编码将其转换,临时存储

  再次转换成 服务器西药的编码,并正真的存储在服务器上

    现在,我们以mysql这个流程说一下,在存入数据和读取数据时的编码转换。

如图

存入数据:

读取数据:

    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时注意设置

  好了,就这么多吧,这些笔记,不光只是抄写,也是加入了一些以前自己的认识和验证的猜想,总的感觉就是:这次算是基本弄明白了,这些编码是怎么一回事了。

  如果有什么错误和不明白的地方,亲大家留言,谢谢!睡觉喽,吼吼、、、、、

mysql字符集基础知识梳理的更多相关文章

  1. MySQL 基础知识梳理

    MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...

  2. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  3. [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式

    SQL 基础知识梳理(六)-  函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...

  4. [SQL] SQL 基础知识梳理(二) - 查询基础

    SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...

  5. [SQL] SQL 基础知识梳理(三) - 聚合和排序

    SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...

  6. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  7. [SQL] SQL 基础知识梳理(五) - 复杂查询

    SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...

  8. Anliven - 基础知识梳理汇总 - 软件测试

    基础知识梳理 - 软件测试 - 概念 基础知识梳理 - 软件测试 - 分类 基础知识梳理 - 软件测试 - 流程 基础知识梳理 - 软件测试 - 用例 基础知识梳理 - 软件测试 - 方法 基础知识梳 ...

  9. [C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型

    引言: 前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解 ...

随机推荐

  1. jQuery实现的Div窗口震动效果实例

    本文实例讲述了jQuery实现的Div窗口震动效果.分享给大家供大家参考.具体如下: 这是一款jQuery窗口震动效果代码,在Div边框内点击一下鼠标,它就开始震动了,适用浏览器:IE8.360.Fi ...

  2. Mysql连接测试代码

    <?php $link=mysql_connect('localhost','root','htuidc'); if($link) echo "success"; ?>

  3. DBLINK 创建与小结

    1.DBLINK 的作用 当用户要跨本地数据库,访问另外一个数据库表中的数据时,本地数据库中必须创建了远程数据库的dblink,通过dblink本地数据库可以像访问本地数据库一样访问远程数据库表中的数 ...

  4. RequireJS和AMD规范

    目录 概述 define方法:定义模块 require方法:调用模块 AMD模式小结 配置require.js:config方法 插件 优化器r.js 参考链接 概述 RequireJS是一个工具库, ...

  5. LevelDB系列之Log文件

    上节内容讲到log文件在LevelDb中的主要作用是系统故障恢复时,能够保证不会丢失数据.因为在将记录写入内存的Memtable之前,会先写入Log文件,这样即使系统发生故障,Memtable中的数据 ...

  6. pthreads多线程数据采集

    以前使用curl的多线程并不是真正的多线程,只是一种模拟的多线程,现在使用pthreads来实现真正意义上的多线程. 下载: windows下: http://windows.php.net/down ...

  7. Delphi 2010初体验,是时候抛弃Delphi 7了

    Delphi 2010已于近日由Embarcadero公司发布.作者Kim Madsen作为一名资深的Delphi开发者,在他的博客中谈到了Delphi 2010的新性能.它的使用感受以及对Delph ...

  8. jquery.unobtrusive-ajax.js单独的用法

    (插件本身已经减少了人力,如果开始无脑开发,简直就是无能,@Ajax里面哪里帮助类生成的其实就是jquery.unobtrusive的一些特性) jquery.unobtrusive是MVC中出现的j ...

  9. ruby on rails 实战(一)

    通过ruby on rails 一步一步搭建个人站点,涉及到的技术有:ruby,rails,javascript,jquery 操作系统:win7 IDE: rubymine 5.4. 第一步,下载安 ...

  10. 刀哥多线程Barrier异步gcd-08-barrier_async

    Barrier 异步 主要用于在多个异步操作完成之后,统一对非线程安全的对象进行更新 适合于大规模的 I/O 操作 代码演练 准备工作 @interface ViewController () { / ...