mysql字符集基础知识梳理
接着上一篇继续来一篇关于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字符集基础知识梳理的更多相关文章
- MySQL 基础知识梳理
MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式
SQL 基础知识梳理(六)- 函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2. ...
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- Anliven - 基础知识梳理汇总 - 软件测试
基础知识梳理 - 软件测试 - 概念 基础知识梳理 - 软件测试 - 分类 基础知识梳理 - 软件测试 - 流程 基础知识梳理 - 软件测试 - 用例 基础知识梳理 - 软件测试 - 方法 基础知识梳 ...
- [C# 基础知识梳理系列]专题六:泛型基础篇——为什么引入泛型
引言: 前面专题主要介绍了C#1中的2个核心特性——委托和事件,然而在C# 2.0中又引入一个很重要的特性,它就是泛型,大家在平常的操作中肯定会经常碰到并使用它,如果你对于它的一些相关特性还不是很了解 ...
随机推荐
- MFC创建对话框组件对应变量并进行设置值(VS2010)
m_path = strFolderPath; UpdateData(FALSE);
- 利用jQuery获取鼠标当前的坐标
文字来源:http://www.smalluv.com/jquery_code_106.html jQuery获取当前鼠标坐标位置: <div id="testDiv"> ...
- Dynamic view
Views are a useful feature of SQL databases, letting us create virtual tables based on SQL select st ...
- 两个和尚抬水有水喝,三个和尚抬水没水喝------IT项目管理之组织架构
说到项目经理岗位,一般的想法是,一个项目只能有一个项目经理,否则责任不明,互相推诿.偏偏IT项目需要有两个甚至三个项目经理.原因何在呢? 典型的IT项目(不包含纯技术或工具类项目)是把用户的需求转化成 ...
- Knockout.Js官网学习(简介)
前言 最近一段时间在网上经常看到关于Knockout.js文章,于是自己就到官网看了下,不过是英文的,自己果断搞不来,借用google翻译了一下.然后刚刚发现在建立asp.net mvc4.0的应用程 ...
- JS中的控制函数调用:call(),apply()和bind()
所有的函数都具有call(),apply()和bind()方法.它们可以在执行方法的时候用一个值指向this,并改变面向对象的作用域. apply方法: 以下的两种表达式是等价的: func(arg1 ...
- SequoiaDB创始人:比MongoDB领先一到两年 打造企业级NoSQL数据库
CSDN.NET 这几年来, NoSQL数据库凭借其易扩展.高性能.高可用.数据模型灵活等特色吸引到了大量新兴互联网公司的青睐,包括国内的淘宝.新浪.京东商城.360.搜狗等都已经在局部尝试NoS ...
- MongoDb 与 Nodejs服务器的启动
1) 启动MongoDB : MongoDB —dbpath databaseNameFolder. 2) 启动数据库 : Mongo DatabaseName. 3) 启动NodeJs: Node ...
- php5 date()获得的时间不是当前时间
php自5.10起加入了时区的设置,在php中显示的时间都是格林威治标准时间,因此便与中国的用户会差八个小时. 修改php.ini中的 date.timezone 参数: [Date] ; Defin ...
- Java transient volatile关键字(转)
Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一 ...