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

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

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

时间: 2024-10-24 21:58:20

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

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

SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 序 目录 What's 数据库 数据库结构 SQL 概要 创建表 删除和更新表 1-1 What's 数据库 1.数据库(Database,DB):将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合.如:大型-银行存储的信息,小型-电话簿. 2.数据库管理系统(Batabase Management Syste

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

SQL 基础知识梳理(六)-  函数.谓词.CASE 表达式 目录 函数 谓词 CASE 表达式 一.函数 1.函数:输入某一值得到相应输出结果的功能,输入值称为“参数”,输出值称为“返回值”. 2.函数的种类: (1)算术函数 - 数值计算 (2)字符串函数 - 字符串操作 (3)日期函数 - 日期操作 (4)转换函数 - 转换数据类型 (5)聚合函数 - 数据聚合 3.算术函数(加.减.乘.除):+.-.*./ [备注]数据类型 NUMBERIC(全体位数,小数位数)可以指定数值的大小. C

Python基础知识梳理 - 第01部分

在开始Python基础知识梳理前, 先安装下环境. 以下过程是在Linux操作系统, root用户下进行的, 主要安装了2.7版本的python, 和pip, ipython, virtualenv等工具, 最后是vim的设置. 1. 安装python. # wget https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tgz Python-2.7.14 # ./configure --prefix=/usr/local/python27

MySQL数据库基础知识

day02 MySQL数据库基础知识 一.基础知识概述: 基础决定你这门课程的学习成败!只有学习好这些基础知识以后,你才能真正的运用自如.才能够对数据库有更深入的了解,道路才会越走越远. 二.基础知识: 1.数据库(database):数据库就好比是一个物理的文档柜,一个容器,把我们整理好的数据表等等归纳起来. 创建数据库命令:        create database 数据库名; 2.查看数据库         show databases; 3.打开指定的数据库         use 

JavaScript基础知识梳理--数组

JavaScript基础知识梳理--数组 1.创建方法 空数组:var obj=new Array(); 指定长度数组: var obj=new Array( size ); 指定元素数组 :  var obj=new Array( 元素1,元素2,....): 单位数组:var obj=new Array[ 元素1,元素2,元素3,...,元素N]; 多维数组:var a=new Array( [数组1],[数组2],[数组3],...,[数组N] ); 2.基本操作 存取数组元素: 单维数组

Java基础知识梳理《一》

一.Java数据类型(简单称之为“四类八种”) java 基本的数据类型长度都是固定的,好处是在实现跨平台时就统一了. 1.整型 byte short int long (分别是1,2,4,8个字节) 类型 存储需求 位数 取值范围 byte 1字节 8位 -128~127 short 2字节 16位 -2^15 ~2^15-1 int 4字节 32位 -2^31~2^31-1 long 8字节 64位 -2^63~2^63-1 当超出int表示范围时,应该使用long型,添加后缀一大写的L 注

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

SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 目录 一.插入数据 1.INSERT 语句的基本语法 --语法: --INSERT INTO <表名>(列1, 列2, ...) VALUES (值1, 值2, ...) INSERT INTO dbo.Shohin ( shohin_id , shohin_mei , shohin_bunrui , hanbai_tanka , s

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

SQL 基础知识梳理(三)- 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 目录 一.对表进行聚合查询 1.聚合函数 (1)5 个常用函数: ①COUNT:计算表中的记录(行)数. ②SUM:计算表中数值列的数据合计值. ③AVG:计算表中数值列的数据平均值. ④MAX:求出表中任意列中数据的最大值. ⑤MIN:求出表中任意列中数据的最小值. (2)聚合:将多行汇总成一行. 图1-1 Shohin 表 2.计算

Js基础知识梳理系列

小序:总是感觉自己的技术一直在原地踏步,想学习一些新的技术,但学起来很吃力,而且总是没有什么实际的收获,似乎进入了所谓的“瓶颈期”.问了一些前辈是否也遇到过同样的问题,他们给我的解决方案是,基础不稳固,再把基础巩固一下.然后学起新的技术会轻松一点点.也是,反思自己曾经走马观花式的学习,确实有很多细腻的技术点没有接触到,所以,我还没有做到大神眼里的“精”.抱着这样的目的,再次翻开<JavaScript高级编程设计>,我将按照着书上的内容和顺序,系统化的学习这本书中的知识.并且在学习的过程中会结合