一、字符集和比较规则介绍
字符集可以理解成字符与二进制数据之间的映射关系,可以用来描述某个范围内的字符的编码规则。
- 编码:将字符映射成二进制数据的过程
- 解码:将二进制数据映射到字符的过程
字符集的比较规则:字符集的比较规则是用于比较两个字符大小的规则,如通过两个字符对应的二进制编码大小来比较等,同一个字符集可以有多种不同的比较规则
二、常见的字符集
- ASCII字符集:一共收录了128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符,采用一个字节来进行编码。
ASCII表
其中 数字的二进制编码对应的十进制范围是 48~57(数字1-9),大写字母是
65~90(A-Z),小写字母是97 ~122(a-z)。 - ISO 8859-1:别名Latin1,一共收录256个字符,它在ASCII的基础上又扩充了128个西欧常用字符。ISO 8859-1也可以使用一个字节来进行编码。
- GB2312:兼容了ASCII,收录了6763个汉字还有其他文字符号682个,当编码ASCII字符集中的字符时使用一个字节进行编码,否则使用两个字节进行编码。
- GBK:兼容了GB2312,在GB2312的基础上对字符范围进行了扩充。
- UTF-8:几乎收录了当今世界各个国家/地区使用的字符,兼容ASCII,采用变长码的方式进行编码,编码一个字符需要1~4个字节。
注意:UTF-8只是Unicode字符集的一种编码方案,Unicode字符集采用UTF-8、UTF-16、UTF-32这几种编码方案。UTF-8使用1~4个字节编码一个字符,UTF-16采用2或4个字节编码一个字符,UTF-32采用4个字节编码一个字符。
三、MySQL中的字符集
1、查看MySQL中的字符集和比较规则
查看MySQL中的字符集可以使用以下命令来查看
show (charset|character) set [like 匹配的模式];
如
其中Maxlen表示该字符集最多需要几个字节来表示一个字符,Default collation表示默认的比较规则
注意:上图中的utf8mb4表示的是UTF-8字符集使用1~4个字节来表示字符,而utf8表示的是utf8mb3是简化版的UTF-8字符集,只使用1 ~3个字节来表示字符。所以如果有需要4个字节进行编码的情况(如存储一些emoji表情)需要使用utf8mb4.
查看MySQL中的比较规则可以使用如下命令查看
show collation [like 匹配的模式]
如查看utf8mb4支持的比较规则
其中Default字段为yes表示默认的比较规则
比较规则的命名:
- 第一段为与其关联的字符集的名称,如上面展示的比较规则第一段都为utf8mb4
- 第二段为该比较规则所应用的语言,如utf8mb4_unicode_ci就是基于标准的Unicode来排序和比较
- 第三段表示该比较规则是否区分语言中的重音、大小写等。
后缀 | 含义 |
---|---|
_ai | 不区分重音 |
_as | 区分重音 |
_ci | 不区分大小写 |
_cs | 区分大小写 |
_bin | 以二进制的方式进行比较 |
2、各个级别的字符集和比较规则
MySQL有4个级别的字符集和比较规则,分别是服务器级别、数据库级别、表级别、列级别
服务器级别和数据库级别的字符集和比较规则如下系统变量来表示
- 服务器级别
系统变量 | 描述 |
---|---|
character_set_server | 服务器级别的字符集 |
collation_server | 服务器级别的比较规则 |
- 数据库级别
系统变量 | 描述 |
---|---|
character_set_database | 当前数据库的字符集 |
collation_database | 当前数据库的比较规则 |
对于服务器级别的字符集和比较规则我们可以通过启动选项或者配置文件来进行设置
对于数据库和表级别的字符集和比较规则我们可以通过创建或修改数据库/表的命令来设置
创建数据库
create database 数据库名
[[default] character set 字符集名称]
[[default] collate 比较规则名称];
修改数据库
alter database 数据库名
[[default] character set 字符集名称]
[[default] collate 比较规则名称];
创建表
create table 表名 (列的信息)
[[default] character set 字符集名称]
[[default] collate 比较规则名称];
修改数据库
alter table 表名
[[default] character set 字符集名称]
[[default] collate 比较规则名称];
对于列级别的
create table 表名(
列名 字符串类型 [character set 字符集名称] [collate 比较规则名称],
其他列...
);
修改时
alter table 表名 modify 列名 字符串类型 [character set 字符串名称] [collate 比较规则名称];
注意:字符集和比较规则互相关联,如果只修改字符集,那么比较规则会自动修改为修改后的字符集默认的比较规则,如果只修改比较规则,那么字符集会自动修改为修改后的比较规则对应的字符集。同时需要了解的是,各个字符集和比较规则的优先程度如下:
列>表>数据库>服务器
3、客户端和服务器通信过程中使用字符集
客户端与服务器通信过程涉及到的编解码过程有
- 客户端发送请求需要把请求字符串编码,一般情况下编码使用的字符集与操作系统的字符集一致。如果在启动客户端时指定了 default-character-set的值,那么将使用该值指定的字符集进行编码。
- 服务器接收请求后(实际上接收到的就是一个字节序列),会将这个字节序列看成是用系统变量character_set_client代表的字符集进行编码的字节序列。服务器每一个连接的客户端维护一个单独的character_set_client变量,这个变量是session级别的。
- 服务器处理请求,服务器在处理请求时(运行过程中)会将其转化为使用session级别的系统变量character_set_connection对应的字符集进行编码的字节序列。
- 服务器生成响应,服务器在生成响应时会将其转化为session级别的系统变量character_set_result对应的字符集进行编码的字节序列。