【mysql】字符集与比较规则
文章目录
- 1. utf8 与 utf8mb4
- 2. 比较规则
- 3. 请求到响应过程中字符集的变化
1. utf8 与 utf8mb4
utf8
字符集表示一个字符需要使用1~4
个字节,但是常用的一些字符使用1~3
个字节就可以表示。而字符集表示一个字符所用的最大字节长度,在某些方面会影响系统的存储和性能,所以设计MySQL的设计者定义了两个概念:
utf8mb3
:阉割过的utf8
字符集,只使用1~3
个字节表示字符。utf8mb4
:正宗的utf8
字符集,使用1~4
个字节表示字符。
- 在MySQL中
utf8
是utf8mb3
的别名,所以之后在MySQL中提到utf8
就意味着使用1~3
个字节来表示一个字符。 - 如果有使用
4
字节编码一个字符的情况,比如存储一些emoji
表情,那就使用utf8mb4
。 - 此外,通过如下指令可以查看MySQL支持的字符集:
show charset;
或
show character set;
- 可以看到 字符集 对应的规则如下,utf8 占用 3 个字节,utf8mb4 占用 4 个字节
2. 比较规则
- 上表中,MySQL版本共支持41种字符集,其中的
Default collation
列表示这种字符集中一种默认的比较规则,里面包含着该比较规则主要作用于哪种语言,比如utf8_polish_ci
表示以波兰语的规则此较,utf8_ spanish_ ci
是以西班牙语的规则比较,utf8_general_ci
是一种通用的比较规则。 - 后缀表示该比较规则是否区分语言中的重音、大小写。具体如下:
后缀 | 英文释义 | 描述 |
---|---|---|
_ai | accent insensitive | 不区分重音 |
_as | accent sensitive | 区分重音 |
_ci | case insensitive | 不区分大小写 |
_cs | case sensitive | 区分大小写 |
_bin | binary | 以二进制方式比较 |
- 最后一列
Maxlen
,它代表该种字符集表示一个字符最多需要几个字节。 - 这里把常见的字符集和对应的
Maxlen
显式如下:
字符集名称 | Maxlen |
---|---|
ascii | 1 |
latin1 | 1 |
gb2312 | 2 |
gbk | 2 |
utf8 | 3 |
utf8mb4 | 4 |
- 常用操作1:
- 查看GBK字符集的比较规则
SHOW COLLATION LIKE 'gbk%';
- 查看UTF-8字符集的比较规则
SHOW COLLATION LIKE 'utf8%';
- 常用操作2:
- 查看服务器的字符集和比较规则
SHOW VARIABLES LIKE '%_server'
- 查看数据库的字符集和比较规则
SHOW VARIABLES LIKE '%_database' ;
- 查看具体数据库的字符集
SHOW CREATE DATABASE dbtest1 ;
- 修改具体数据库的字符集
ALTER DATABASE dbtest1 DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_ general_ ci';
- 说明1:
utf8_unicode_ci
和utf8_ general_ci
对中、英文来说没有实质的差别。
utf8_general_ci
校对速度快,但准确度稍差。
utf8_unicode_ci
准确度高,但校对速度稍慢。
一般情况,用
utf8_general_ci
就够了,但如果应用有德语、法语或者俄语,请一定使用utf8_unicode_ci
。
说明2:
修改了数据库的默认字符集和比较规则后,原来已经创建的表格的字符集和比较规则并不会改变,如果需要修改,那只能单独修改。常用操作3:
- 查看表的字符集
show create table 表名
- 查看表的比较规则
show table status from 数据库名 like '表名';
- 修改表的字符集和比较规则
ALTER TABLE 表名 DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
3. 请求到响应过程中字符集的变化
- 从客户端发往服务器的请求本质上就是一个
字符串
,服务器向客户端返回的结果本质上也是一个字符串,而字符串其实是使用某种字符集编码的二进制数据
。这个字符串可不是使用一种字符集的编码方式一条道走到黑的,从发送请求到返回结果这个过程中伴随着多次字符集的转换
,在这个过程中会用到3
个系统变量,如下:
系统变量 | 描述 |
---|---|
character_set_client | 服务器解码请求时使用的字符集 |
character_set_connection | 服务器处理请求时会把请求字符串从character_set_client 转为character_set_connection |
character_set_results | 服务器向客户端返回数据时使用的字符集 |
这几个系统变量在计算机上的默认值如下(不同操作系统的默认值可能不同):
为了体现出字符集在请求处理过程中的变化,这里特意修改一个系统变量的值:
mysql> set character_set_connection = gbk;
Query 0K,
0 rows affected (0.00 sec)
- 现在假设客户端发送的请求是下边这个字符串:
SELECT * FROM t WHERE s = '我';
- 为了方便理解这个过程,只分析字符 ‘
我
’ 在这个过程中字符集的转换。 - 现在看一下在请求从发送到结果返回过程中字符集的变化:
- 客户端发送请求所使用的字符集
一般情况下客户端所使用的字符集和当前操作系统一致,不同操作系统使用的字符集可能不一样,如下:
- 类Unix系统使用的是utf8
- Windows使用的是gbk
- 当客户端使用的是
utf8
字符集,字符 ‘我
’ 在发送给服务器的请求中的字节形式就是:0xE68891
提示:
如果使用的是可视化工具,比如navicat之 类的,这些工具可能会使用自定义的字符集来编码发送到服
务器的字符串,而不采用操作系统默认的字符集(所以在学习的时候还是尽量用命令行窗口)。
服务器接收到客户端发送来的请求其实是一串二进制的字节,它会认为这串字节采用的字符集是
character_set_client
,然后把这串字节转换为character_set_connection
字符集编码的字符。由于我的计算机上character_set_client
的值是utf8
,首先会按照utf8
字符集对字节串0xE68891
进行解码,得到的字符串就是’我
’,然后按照character_set_connection
代表的字符集,也就是gbk
进行编码,得到的结果就是字节串0xCED2
。因为表
t
的列col
采用的是gbk
字符集,与character_set_connection
一致,所以直接到列中找字节值
为0xCED2
的记录,最后找到了一条记录。
提示:
如果某个列使用的字符集和character_set_connection代表的字符集不一致的话,还需要进行一次字符集转换。
- 上一步骤找到的记录中的
col
列其实是一个字节串exCED2
,col
列是采用gbk
进行编码的,所以首先会将这个字节串使用gbk
进行解码,得到字符串‘我
’ ,然后再把这个字符串使用character_set_results
代表的字符集,也就是utf8
进行编码,得到了新的字节串:0xE68891
,然后发送给客户端。 - 由于客户端是用的字符集是
utf8
,所以可以顺利的将0xE68891
解释成字符我,从而显示到我们的显示器上,所以我们读懂了返回的结果。
演示图如下:
从这个分析中可以得出这么几点需要注意的地方:
服务器认为客户端发送过来的请求是用
character_set_client
编码的。
假设你的客户端采用的字符集和character_set_client
不一样的话,这就会出现识别不准确的情况。比如我的客户端使用的是utf8
字符集,如果把系统变量character_set_client
的值设置为ascii
的话,服务器可能无法理解我们发送的请求,更别谈处理这个请求了。服务器将把得到的结果集使用
character_set_results
编码后发送给客户端。
假设你的客户端采用的字符集和character_ set_ results 不一样的话,这就可能会出现客户端无法解码结果集的情况,结果就是在你的屏幕上出现乱码。比如我的客户端使用的是utf8字符集,如果把系统变量character_set_results
的值设置为ascii
的话,可能会产生乱码。character_set_connection
只是服务器在将请求的字节串从character_set_client
转换为
character_set_connection
时使用,一定要注意,该字符集包含的字符范围一定涵盖请求中的字符,要不然会导致有的字符无法使用character_set_connection
代表的字符集进行编码。经验:
开发中通常把character_set_client
、character_set_connection
、character_set_results
这三个系统变量设置成和客户端使用的字符集一致的情况,这样减少了很多无谓的字符集转换。为了方便我们设置,MySQL提供了一条非常简便的语句:
SET NAMES = 字符集名;
- 这一条语句产生的效果和下面执行这3条语句的效果是一样的:
SET character_set_client = 字符集名;
SET character_set_connection = 字符集名;
SET character_set_results = 字符集名;
- 比方说我的客户端使用的是
utf8
字符集,所以需要把这几个系统变量的值都设置为utf8
:
mysql> SET NAMES utf8;
- 另外,如果想在启动客户端的时候就把
character_set_client
、character_set_connection
、character_set_results
这三个系统变量的值设置成一样的,可以在启动客户端的时候指定一个叫
default-character-set
的启动选项,在配置文件中设置:
[client]
default-character-set=utf8
- 上述语句使用的效果和执行一遍
SET NAMES utf8
是一样的,都会将那三个系统变量的值设置成utf8
。
【mysql】字符集与比较规则相关推荐
- MYSQL字符集与校对规则
MYSQL字符集与校对规则 一. 字符集与校队规则概述 简单的说字符集就是一套文字符号及编码.比较规则的集合. 目前支持中文的常用的字符集有UTF-8.GBK.GB2312等,MYSQL服务器支持多种 ...
- MySQL字符集与排序规则
MySQL字符集与排序规则 MySQL支持的字符集 字符集与排序规则 排序规则的命名 使用字符集与排序规则 服务器级别的字符集 数据库级别的字符集 表级别的字符集 列级别的字符集 字符串级别的字符集 ...
- 【宋红康 MySQL数据库 】【高级篇】【02】MySQL字符集、比较规则、大小写规范、sql_mode
持续学习&持续更新中- 学习态度:守破离 [宋红康 MySQL数据库 ][高级篇][02]MySQL字符集.比较规则.大小写规范.sql_mode 默认字符集 MySQL8 MySQL5 修改 ...
- mysql字符集与校对规则设置_mysql中的字符集和校对规则(mysql校对集)
1.简要说明介绍 字符集和校对规则 字符集是一套符号和编码.校对规则是在字符集内用于比较字符的一套规则. MySql在collation提供较强的支持,oracel在这方面没查到相应的资料. 不同字符 ...
- mysql字符集校对和规则
2019独角兽企业重金招聘Python工程师标准>>> 字符集和校对规则 字符集是一套符号和编码.校对规则是在字符集内用于比较字符的一套规则. MySql在collation提供 ...
- MySQL 字符集 和 排序规则
字符集 用到字符的地方就会用到字符集,通过字符集对字符串编码转换成二进制序列,进而可以对这个二进制序列进行存储或传输,之后在读取的时候通过该字符集对二进制序列进行解码得到字符串内容,这就是字符集的用途 ...
- mysql字符集的排序规则_MySql字符集与排序规则详解
前段时间往MySQL中存入emoji表情或生僻字.繁体字时,报错无法添加,研究后发现这是字符集编码的问题,今天就来分析一下各个字符集与排序规则 一.字符集 先说字符,字符是各种文字和符号的总称,包括各 ...
- mysql字符集与校对规则设置_MySQL 字符集与校对规则
1.创建对象时的默认值MySQL 的设置可以分为两类 , 创建对象时的默认值 , 在服务器和客户端通信时的设置 . MySQL 服务器有默认的字符集和校对规则 , 每个数据库也有自己的默认值 . 每个 ...
- MySQL字符集与比较规则
编码解码 将字符映射成二进制数据的过程称为编码,将二进制数据映射成字符的过程称为解码. 比较规则 将不同字符进行大小比较的规则,注意同一种字符集可以有多种比较规则. MySQL中的字符集和比较规则有四 ...
- mysql字符集编码和排序规则
环境: mysql 5.7 26 DBeaver 21.1.2.202107041908 参考:<MySQL字符集与排序规则总结> 建议先阅读:<细说ASCII.GB2312/GBK ...
最新文章
- 1266: [AHOI2006]上学路线route
- EasyHook远程代码注入
- 关于有序二维矩阵查找和字符串替换的两道算法题
- 46 CO配置-控制-利润中心会计-创建虚拟利润中心
- 特别引人注目的头像_设计样式指南:构建引人注目的产品的要素
- 【CAS】Implementing generic double-word compare and swap for x86/x86-64
- SAP License:无师自通学SAP-开篇
- android崩解日志,android – 使用rxJava2和改造的UndeliverableException
- 我的世界java凋零_我的世界:玩家还原Java版已“消失”的三个结构,造型让人难忘?...
- c语言我想你,c语言土味情话
- 畅言普通话软件测试准确率高吗,畅言普通话测试准确吗?畅言普通话准确度介绍...
- 如何分析一个开源工程的代码
- 时间轮(TimeWheel)的设计与实现
- 计算机电源带不起来,电源板带不起负载维修思路总结
- tps,rps,qps,hps的区别
- 万答#14,xtrabackup8.0怎么恢复单表
- 2016互联网和通信企业校招面经和进展记录
- css和图片如何实现圆角边框
- MySQL数据库使用——MySQL数据库管理
- 关于虚拟机复制/移动/克隆已有镜像发生无法上网的情况。
热门文章
- C语言(进阶)数据的存储修炼内功
- 【装机必备】Win软件卸载工具
- Android 新增外设Service添加供app使用
- Kickstart无人值守安装
- Spring Cloud入门-Sentinel实现服务限流、熔断与降级(Hoxton版本)
- Android开发工程师文集-layout_weight讲解
- 视频图像传输与显示(4)——数字电视信号标准ITU-R BT.601和ITU-R BT.656简介
- python在图片上绘制标注框
- Django 项目试炼blog(10) --补充 滑动验证码
- 十分钟入门Pandas