MySQL字符集和比较规则
MySQL字符集和比较规则
字符集和比较规则简介
字符集: 描述字符与二进制数据的映射关系
比较规则:比较指定字符集中的字符的规则
字符集
我们知道,计算机无法直接存储字符串,实际存储的都是二进制数据。字符集是有限的,也就是字符范围,比如ASCII字符集包含了128个字符与进制数据的映射关系。将字符根据编码规则映射成二进制数据的过程叫做编码,将二进制数据根据编码规则映射到字符的过程叫做解码。
举个例子,在ASCII字符集中,存在如下映射关系:
'A' -> 01000001(十六进制为0x41)
'B' -> 01000010(十六进制为0x42)
'a' -> 01100001(十六进制为0x61)
'b' -> 01100010(十六进制为0x62)
'我' -> 不存在,因为ASCII字符集的字符范围里并不存在'我'与8位组的对应关系
查看字符集
命令:SHOW (CHARSET | CHARACTER SET) [LIKE 匹配的模式]
mysql> SHOW CHARSET;
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| ascii | US ASCII | ascii_general_ci | 1 |
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
...
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| utf8mb3 | UTF-8 Unicode | utf8mb3_general_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.01 sec)
本文使用的MySQL8.0版本中共支持41中字符集(仅列出了常用字符集)。其中Default collation为该字符集默认的比较规则,Maxlen是最多需要使用几个字节来映射一个字符。
比较规则
在确定字符集之后,还需要比较字符集中两个字符的大小或是否相等,此时,就需要用到字符集的比较规则。最简单的比较规则就是:直接比较两个字符对应的二进制编码的大小。一个字符集可以有多种比较规则。
查看比较规则
命令:SHOW COLLATION [LIKE 匹配的模式]
mysql> SHOW COLLATION LIKE '%utf8mb4%';
+----------------------------+---------+-----+---------+----------+---------+---------------+
| Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute |
+----------------------------+---------+-----+---------+----------+---------+---------------+
| utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD |
| utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 | NO PAD |
| utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 | NO PAD |
| utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 | NO PAD |
...
| utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 | PAD SPACE |
...
| utf8mb4_spanish_ci | utf8mb4 | 231 | | Yes | 8 | PAD SPACE |
| utf8mb4_zh_0900_as_cs | utf8mb4 | 308 | | Yes | 0 | NO PAD |
+----------------------------+---------+-----+---------+----------+---------+---------------+
89 rows in set (0.00 sec)
上述代码块中展示了MySQL8.0中utf8mb4这个字符集的常用比较规则。这些比较规则是有规律的。
- 比较规则的名称以其关联的字符集名称开头。
- 后面紧跟着该比较规则所应用的语言,比如utf8mb4_spanish_ci表示西班牙语的比较规则。utf8mb4_general_ci是一种通用的比较规则。
- 名称后缀表示该规则是否区分大小写、语言中的重音等。具体后缀如下表所示
| 后缀 | 英文释义 | 描述 |
|---|---|---|
| _ai | accent insensitive | 不区分重音 |
| _as | accent sensitive | 区分重音 |
| _ci | case insensitive | 不区分大小写 |
| _cs | case sensitive | 区分大小写 |
| _bin | binary | 以二进制方式比较 |
常用的字符集
计算机是美国人发明的,因此ACISS字符集中包含了26个英文字母和一些字符就足够美国人日常使用了。但是如果一些其他国家和地区想要使用计算机,就必须有一套包含自身语言的字符集,比如GBK、IOS-8859-1等字符集。以下是一些常用的字符集:
ASCII:包含128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符(回车、制表符等)。由于ASCII字符集总共才128个字符,所以使用**一个字节(8位)**就足够保存了。GB2312:收录6763个汉字以及拉丁字母、希腊字母等,兼容ASCII字符集。使用GB2312编码时,如果该字符存在于ASCII字符集中,则使用一字节编码,否则采用两字节编码。这种使用不同不同字节数来表示一个字符的编码方式称为变长编码。GBK(国标扩展的首字母):GBK对GB2312进行了扩充,编码方式兼容GB2312。Unicode:几乎收录了各个国家使用的字符,并且还在不断扩充。Unicode仅定义了字符和数值的映射关系。具体存储需要看是UTF-8、UTF-16、UTF-32等。
Unicode字符集
Unicode定义了映射关系,但是却没有规定如何存储。一个码值为 0x41 的字符,只需要 1字节 就可以存下,但是码值 0x9ED1 的字符需要 2字节 的空间才可以装下,而更靠后的字符可能会需要 3字节 甚至 4字节 的空间。
UTF-16 和 UTF-32
我们可以规定,一个字符使用四个字节存储,也就是 32 位,这样就能涵盖现有 Unicode 包含的所有字符,这种编码方式叫做 UTF-32(UCS Transformation Format 的缩写)。UTF-32 的规则虽然简单,但是缺陷也很明显,假设使用 UTF-32 和 ASCII 分别对一个只有西文字母的文档编码,前者需要花费的空间是后者的四倍(ASCII 每个字符只需要一个字节存储)。
UTF-16是一种变长字符编码, 它将字符编码成 2 字节 或者 4 字节。与UTF-32类似,同样存在着空间浪费的问题。
UTF-8
在存储和网络传输中,通常使用更为节省空间的变长编码方式 UTF-8,UTF-8 代表 8 位一组表示 Unicode 字符的格式,采用变长编码,使用 1 - 4 个字节来表示字符,比如下面这样:
'C' -> 01000011(十六进制为0x43) // 1字节
'斌' -> 11100110 10010110 10001100(十六进制为0xE6968C) // 3字节
变长编码通常需要存储表示字节数的信息,让计算机知道字符是以几个字节来存储的。
UTF-8用首字节的前几位表示编码的字节数:
- 首字节以0开头,表示单字节编码
- 首字节以110开头,表示双字节编码,后续字节以10开头
- 首字节以1110开头,表示三字节编码,后续字节以10开头
- 首字节以11110开头,表示四字节编码,后续字节以10开头

举个例子,就拿上方代码块的 ‘斌’ 这个字符,
-
通过中文转Unicode编码工具可知码值为 \u658C。
-
转换为二进制数
01100101 10001100,我们得到码点后采用UTF-8将其存储到计算机中,我们需要16位有效比特位,从上图可以看出只要 3字节 即可表示。 -
将二进制数代入规则:1110
01101001 01101000 1100(红色字体为有效比特位)
字符集和比较规则的应用
各级别的字符集和比较规则
在MySQL中可以从服务器、数据库、表、列这几个维度分别设置和查看字符集及其比较规则。
服务器级别
| 系统变量 | 描述 |
|---|---|
| character_set_server | 服务器级别的字符集 |
| collation_server | 服务器级别的比较规则 |
MySQL8.0中默认的服务器字符集为utf8mb4,比较规则为utf8mb4_0900_ai_ci。
mysql> SHOW variables like 'character_set_server';
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+mysql> SHOW variables like 'collation_server';
+------------------+--------------------+
| Variable_name | Value |
+------------------+--------------------+
| collation_server | utf8mb4_0900_ai_ci |
+------------------+--------------------+
修改MySQL系统变量的方式可以通过启动选项或者在服务器程序运行过程中使用SET语句来修改。也可以修改配置文件的*[server]*组信息。
数据库级别
具体数据库的字符集和比较规则可以在创建是指定,创建后也可以通过ALTER语句来修改。
# 创建或修改数据库时指定字符集
(CREATE | ALTER) DATABASE 数据库名称[CHARACTER SET 字符集名称][COLLATE 比较规则名称];
| 系统变量 | 描述 |
|---|---|
| character_set_database | 当前数据库的字符集 |
| collation_database | 当前数据库的比较规则 |
数据库级别的两个系统变量与服务器级别不同的是,这我们不能通过修改这两个变量的值来改变当前数据库的字符集和比较规则(修改可以通过ALTER语句)。
创建数据库时也可以不指定字符集和比较规则,这将默认使用服务器级别的值。
表级别
与数据库级别类似,表的字符集和比较规则也可以在创建表时指定,或创建后修改。
# 创建表时指定
CREATE TABLE 表名 (列信息)[CHARACTER SET 字符集名称][COLLATE 比较规则名称];# 修改表的字符集
ALTER TABLE 表名[CHARACTER SET 字符集名称][COLLATE 比较规则名称];
创建数据库时同样可以不指定字符集和比较规则,这将继承数据库级别。
列级别
对于存储字符串的列,同一个表中不同的列可以有不同的字符集和比较规则。在创建和修改列的时候可以指定该列的字符集和比较规则。
# 创建时指定
CREATE TABLE 表名(列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],...
);# 修改列的字符集
ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集] [COLLATE 比较规则名称];
同样,如果没有指定,就会使用表级别的。需要注意的是,修改指定列的字符集时,如果列中存储的数据不能用修改后的字符集进行表示,则会发生错误,中断修改操作。
小结:各级别的字符集和比较规则
- 如果创建或修改列时没有显式指定字符集和比较规则,则默认使用表的字符集和比较规则。
- 如果创建表时没有显式指定,则默认使用数据库的。
- 如果创建数据库时没有显式指定,则该数据库默认使用服务器的。
知道列的字符集后,就能知道某个列存储的实际数据所占用的存储空间大小。
客户端和服务器通信过程中的字符集
什么是乱码?计算机对某个字节序列进行解码时,采用的字符集和编码时使用的字符集不一致,就会产生乱码。例如’我’在utf-8下字节序列为0xE68891,若采用GBK解码,会先读前两个字节。
客户端发送阶段
使用MySQL自带的mysql客户端程序发送请求时(如下图),客户端编码请求字符串时使用的字符集与操作系统当前使用的字符集一致。

在Windows系统中,可以在启动客户端时使用命令default-character-set指定字符集(Unix系统慎用,指定字符集与操作系统不一致时,会乱码)。
mysql --default-character-set=utf8
在连接服务端时,客户端将默认的字符集信息(或者通过上述方式指定字符集)与用户名、密码等信息一起发送给服务器。服务端收到后将character_set_client、character_set_connetion、character_set_results这3个系统变量的值初始化为客户端传递的字符集,作用请参考 2.2.2 节。
服务端处理阶段
| 系统变量 | 描述 |
|---|---|
| character_set_client | 服务器认为请求是按照该系统变量指定的字符集进行编码 |
| character_set_connection | 服务器处理请求时,把请求字节序列从character_set_client转换为character_set_connection对应的字符集 |
| character_set_results | 服务器采用该系统变量指定的字符集对返回给客户端的字符串进行编码 |
- 接收请求
服务端接收到客户端的请求的字节序列时,根据系统变量character_set_client对应的字符集解码该字节序列,该变量是SESSION级别的,可以对不同客户端设置不同的解码规则。
- 处理请求
在真正处理请求时,又会将其转换为系统变量character_set_connection对应的字符集进行编码的字节序列,该变量也是SESSION级别的,与之配套的另一个变量是collation_connection。
将字节序列根据 character_set_client 转码为 character_set_connection 是为了确保数据在不同环节中的一致性、避免字符集不匹配问题、提高系统的灵活性和兼容性。这样可以保证 MySQL 在处理请求时能够正确解析和处理不同字符集编码的数据,确保数据的完整性和准确性。
CREATE TABLE table1(col VARCHAR(100)
) ENGINE=InnoDB CHARSET=utf8;
假设当前的character_set_connection为GBK。
当执行如下查询语句:
SELECT * FROM table1 WHERE col = '斌';
表中的col字段是UTF-8编码,但连接为GBK,在这种情况下,列的字符集和排序规则的优先级会更高,因此会将 ‘斌’ 从 GBK 转为 UTF-8 后,使用 c 列的比较规则进行比较。
- 返回结果
服务端将查询结果从对应列的字符集编码转换为character_set_results系统变量对应的字符集编码后的字节序列,之后再发送给客户端。该变量亦是SESSION级别的。
客户端接收结果阶段
在此阶段,客户端收到的响应也是一个字节序列。对于Windows系统,客户端会使用MySQL客户端的默认字符集来解码这个字节序列(启动项 –default-character-set)。但是 Unix 系统会使用系统默认编码直接输出到控制台,因此可能会产生乱码。如下场景:
- 查看当前操作系统的默认编码

-
在 Mac OS 启动MySQL客户端时使用
–default_character_set=gbk。 -
客户端与服务端建立连接时指定了编码方式为 GBK ,因此服务端将会返回 GBK 编码后的字节序列。

- Mac OS 会直接将序列输出到终端,使用的是系统的编码 UTF-8 ,因此出现乱码(windows会使用客户端的编码)。

相关文章:
MySQL字符集和比较规则
MySQL字符集和比较规则 字符集和比较规则简介 字符集: 描述字符与二进制数据的映射关系 比较规则:比较指定字符集中的字符的规则 字符集 我们知道,计算机无法直接存储字符串,实际存储的都是二进制数据。字符集是有限的ÿ…...
备忘录模式(Memento Pattern)
定义 备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不破坏封装性的前提下捕获一个对象的内部状态,并在以后将对象恢复到该状态。备忘录模式通常用于实现撤销操作(Undo)或历史记录(H…...
LeetCode 刷题 [C++] 第121题.买卖股票的最佳时机
题目描述 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…...
ORACLE 基础
一.ORACLE简介 1.1什么是oracle ORACLE 数据库系统是美国 ORACLE 公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或 B/S 体系结构的数据库之一。 ORACLE 通常应用于大型系统的数据库产品。…...
Adobe illustrator CEP插件调试
1.创建插件CEP面板,可以参考:http://blog.nullice.com/%E6%8A%80%E6%9C%AF/CEP-%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B/%E6%8A%80%E6%9C%AF-CEP-%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B-Adobe-CEP-%E6%89%A9%E5%B1%95%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8…...
学会玩游戏,智能究竟从何而来?
最近在读梅拉妮米歇尔《AI 3.0》第三部分第九章,谈到学会玩游戏,智能究竟从何而来? 作者: [美] 梅拉妮米歇尔 出版社: 四川科学技术出版社湛庐 原作名: Artificial Intelligence: A Guide for Thinking Humans 译者: 王飞跃 / 李玉珂 / 王晓…...
Unity 常用操作
2D素材网站 https://craftpix.net/ https://itch.io/game-assets/tag-2d/tag-backgrounds 3D素材资源网址 https://www.mixamo.com/#/ 场景常用操作: 快捷键:QWER Q:Q键或鼠标中键,可以拉动场景。 W:选中物体后&…...
【计算机网络_应用层】协议定制序列化反序列化
文章目录 1. TCP协议的通信流程2. 应用层协议定制3. 通过“网络计算器”的实现来实现应用层协议定制和序列化3.1 protocol3.2 序列化和反序列化3.2.1 手写序列化和反序列化3.2.2 使用Json库 3.3 数据包读取3.4 服务端设计3.5 最后的源代码和运行结果 1. TCP协议的通信流程 在之…...
Doris实战——银联商务实时数仓构建
目录 前言 一、应用场景 二、OLAP选型 三、实时数仓构建 四、实时数仓体系的建设与实践 4.1 数仓分层的合理规划 4.2 分桶分区策略的合理设置 4.3 多源数据迁移方案 4.4 全量与增量数据的同步 4.5 离线数据加工任务迁移 五、金融级数仓稳定性最佳实践 5.1 多租户资…...
代码随想录算法训练营第七天
● 自己看到题目的第一想法 第454题.四数相加II 方法: 方法一: 暴力法 思路: 注意: 代码: class Solution { public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<i…...
文件操作和IO(2):Java中操作文件
目录 一、File的属性 二、File的构造方法 三、File的方法 四、代码示例 1、getName,getParent,getPath方法 2、getAbsolutePath,getCanonicalPath方法 3、exists,isDirectory,createNewFile方法 4、createNewF…...
人工智能-零基础
机缘 扩充下知识栈,准备零基础开始 人工智能零基础 日常 日常水一下博客… 憧憬 努力成为一个会人工智能的程序员...
网络爬虫部分应掌握的重要知识点
目录 一、预备知识1、Web基本工作原理2、网络爬虫的Robots协议 二、爬取网页1、请求服务器并获取网页2、查看服务器端响应的状态码3、输出网页内容 三、使用BeautifulSoup定位网页元素1、首先需要导入BeautifulSoup库2、使用find/find_all函数查找所需的标签元素 四、获取元素的…...
git命令笔记
文章目录 0、参考文档1、常用指令git checkout系列git pull系列git push系列git reset系列git branch系列git log系列git revert 撤销某次提交git diff其他 2、查看和修改用户名和邮箱,生成密钥other 0、参考文档 Git使用教程:最详细、最傻瓜、最浅显、…...
微服务day03-Nacos配置管理与Nacos集群搭建
一.Nacos配置管理 Nacos不仅可以作为注册中心,可以进行配置管理 1.1 统一配置管理 统一配置管理可以实现配置的热更新(即不用重启当服务发生变更时也可以直接更新) dataId格式:服务名-环境名.yaml,分组一般使用默认…...
DFS剪枝
剪枝 将搜索过程中一些不必要的部分剔除掉,因为搜索过程构成了一棵树,剔除不必要的部分,就像是在树上将树枝剪掉,故名剪枝。 剪枝是回溯法中的一种重要优化手段,方法往往先写一个暴力搜索,然后找到某些特…...
基于SpringBoot多模块项目引入其他模块时@Autowired无法注入
基于SpringBoot多模块项目引入其他模块时Autowired无法注入 一、问题描述1、解决方案 一、问题描述 启动Spring Boot项目时报 Could not autowire. No beans of ‘xxxxxxxx’ type found. 没有找到bean的实例,即spring没有实例化对象,也就无法根据配置文…...
每日一题——LeetCode1566.重复至少K次且长度为M的模式
方法一 暴力枚举 var containsPattern function(arr, m, k) {const n arr.length;for (let l 0; l < n - m * k; l) {let offset;for (offset 0; offset < m * k; offset) {if (arr[l offset] ! arr[l offset % m]) {break;}}if (offset m * k) {return true;}}r…...
代码随想录刷题笔记-Day27
1. 全排列 46. 全排列https://leetcode.cn/problems/permutations/ 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],…...
【小沐学GIS】QGIS安装和入门使用
文章目录 1、简介2、下载和安装3、使用3.1 XYZ Tiles3.2 WMS / WMTS3.3 GeoJson文件加载 4、在线资源结语 1、简介 QGIS是一款开源地理信息系统。该项目于2002年5月诞生,同年6月作为SourceForge上的一个项目建立。QGIS目前运行在大多数Unix平台、Windows和macOS上。…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
