3_字符集和比较规则
字符集概念
在计算机中只能存储二进制数据,通过建立字符与二进制数据的映射关系,进而存储字符串。
本质为字符的编码规则。
- 界定字符范围,选择要映射成二进制数据的字符集合;
- ASCII字符集
- 共收录128个字符;
- 包括空格、标点符号、数字、大小写字母和一些不可见字符;
- ASCII字符集
- 映射关系
- 将一个字符映射成一个二进制数据,即编码;
- 例如 'a'——》01100001
- 将一个二进制数据映射到一个字符,即解码;
- 例如 01100001——》'a'
- 将一个字符映射成一个二进制数据,即编码;
比较规则概念
在同一个字符集中,如何比较两个字符的大小?
同一种字符集可以有多种比较规则
- 直接比较这两个字符对应的二进制编码的大小,即二进制比较规则;
- 将两个大小写不同的字符全都转为大写或者小写,再比较这两个字符对应的二进制数据;
重要的字符集
- ASCII字符集
- 共收录128个字符;
- 包括空格、标点符号、数字、大小写字母和一些不可见字符;
- 使用1个字节来进行编码;
- ISO 8859-1字符集,latin1
- 共收录256个字符;
- ASCII字符集 + 128个西欧常用字符(包括德法两国的字母);
- GB2312字符集
- 收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母;
- 兼容ASCII字符集;
- GBK字符集
- 扩容并兼容ASCII字符集;
- utf8字符集
- 收录全球的所有字符,并且在不断地扩充;
- utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方 案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符;
- 对于同一个字符,不同字符集可能有不同的编码方式。比如对于汉字'我'
- ASCII字符集中没有收录这个字符;
- gb2312编码:0xCED2;
- utf8编码:0xE68891;
MySQL支持
在MySQL中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能。
- 设置字符集utf8mb3/utf8;
- utf8mb4:utf8字符集,使用1~4个字节表示字符;
- utf8mb3:阉割过的utf8字符集,只使用1~3个字节表示字符;
- 在MySQL中utf8是utf8mb3的别名;
- 除非存在使用4字节编码一个字符的情况,才设置utf8mb4,例如存储一些emoji表情;
- 查看字符集
SHOW CHARSET [LIKE 匹配的模式];
,在MySQL命令中用全称CHARACTER SET;
- 查看比较规则
SHOW COLLATION [LIKE 匹配的模式];
MySQL应用
级别 | 查看 字符集/比较规则 |
初始化 字符集/比较规则 |
修改 字符集/比较规则 |
默认值 |
---|---|---|---|---|
服务器级别 | SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server'; |
启动项/配置文件 [server] character_set_server=gbk collation_server=gbk_chinese_ci |
运行时SET语句 | utf8 utf8_general_ci |
数据库级别 | USE DATABASE <数据库名> SHOW VARIABLES LIKE 'character_set_database'; SHOW VARIABLES LIKE 'collation_database'; |
CREATE DATABASE <数据库名> [CHARSET 字符集名称] [COLLATE 比较规则名称]; |
ALTER DATABASE <数据库名> [CHARSET 字符集名称] [COLLATE 比较规则名称]; |
默认服务器级别的值 |
表级别 | show create table <表名>; show table status from <数据库名> like <表名>; |
CREATE TABLE <表名> (列的信息) [CHARSET 字符集名称] [COLLATE 比较规则名称]; |
ALTER TABLE <表名> [CHARSET 字符集名称] [COLLATE 比较规则名称]; |
默认数据库级别的值 |
列级别 | 同上 | CREATE TABLE 表名( 列名 字符串类型 [CHARSET 字符集名称] [COLLATE 比较规则名称], 其他列...); |
ALTER TABLE 表名( 列名 字符串类型 [CHARSET 字符集名称] [COLLATE 比较规则名称]); |
默认表级别的值 |
- 在转换字符集时,如果存储的数据不能用待转换的字符集表示,会发生乱码;
- 只修改字符集,则比较规则将变为修改后的字符集默认的比较规则;
- 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集;
字符集转换
字符串'我'从utf8字符集转换为gbk字符集
- 字节串0xE68891按照utf8字符集解码为字符串'我';
- 字符串'我'按照gbk字符集编码为字节串0xCED2;
- 实际上指的是对应字符串的字节串变化;
MySQL字符集转换
系统变量 | 描述 |
---|---|
character_set_client |
服务器解码的字符集 |
character_set_connection |
服务器处理请求的字符集 |
character_set_results |
服务器返回数据的字符集 |

character_set_client、character_set_connection、character_set_results这三个系统变量与客户端使用的字符集设置为一致。
SET NAMES 字符集名;
等价于
SET character_set_client = 字符集名;
SET character_set_connection = 字符集名;
SET character_set_results = 字符集名;
MySQL比较规则
在对字符串做比较或者对字符串列做排序时没有得到想象中的结果,需要思考是否由比较规则引起。