一、字符集和比较规则简介
1.1
字符集简介
计算机中只能存储二进制数据,存储字符串则是通过字符与二进制数据的映射关系。
将一个字符映射成一个二进制数据的过程也叫做
编码
,将一个二进制数据映射到一个字符的过程叫做解码
。
1.2 一些重要的字符集
ASCII
字符集
共收录
128
个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。
ISO 8859-1
字符集
共收录
256
个字符,是在
ASCII
字符集的基础上又扩充了
128
个西欧常用字符
(
包括德法两国的字母
),也可以 使用
1
个字节来进行编码。这个字符集也有一个别名
latin1
。
GB2312
字符集
收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字
6763个, 其他文字符号
682
个。同时这种字符集又兼容
ASCII
字符集,所以在编码方式上显得有些奇怪:
如果该字符在 ASCII
字符集中,则采用
1
字节编码。
否则采用2
字节编码
GBK
字符集
GBK
字符集只是在收录字符范围上对
GB2312
字符集作了扩充,编码方式上兼容
GB2312
。
utf8
字符集
这种字符集兼容
ASCII 字符集,采用变长编码方式,编码一个字符需要使用
1
~
4
个字节。
utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个 字符,utf32使用4个字节编码一个字符。
二、MySQL中支持的字符集和排序规则
2.1 MySQL
中的
utf8
和
utf8mb4
两个概念:
utf8mb3 :阉割过的
utf8
字符集,只使用
1
~
3
个字节表示字符。
utf8mb4 :正宗的
utf8
字符集,使用
1
~
4
个字节表示字符。
在
MySQL
中
utf8
是
utf8mb3
的别名
2.2
字符集的查
查看当前 MySQL
中支持的字符集可以用下边这个语句:
SHOW (CHARACTER SET|CHARSET) [LIKE 匹配的模式];
2.3
比较规则的查看
查看 MySQL
中支持的比较规则的命令如下:
SHOW COLLATION [LIKE 匹配的模式];
三、字符集和比较规则的应用
3.1
各级别的字符集和比较规则
MySQL 有
4
个级别的字符集和比较规则,分别是:
服务器级别
数据库级别
表级别
列级别
3.1.1
服务器级别
MySQL 提供了两个系统变量来表示服务器级别的字符集和比较规则:
3.1.2
数据库级别
我们在创建和修改数据库的时候可以指定该数据库的字符集和比较规则,具体语法如下:
CREATE DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
ALTER DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
character_set_database 和 collation_database 这两个系统变量是只读的,我们不能通过修改这两个变量的值而改变当前数据库的字符集和比较规则。
3.1.3
表级别
我们也可以在创建和修改表的时候指定表的字符集和比较规则,语法如下:
CREATE TABLE 表名 (列的信息)
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]]
ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]
3.1.4
列级别
对于存储字符串的列,
同一个表中的不同的列也可以有不同的字符集和比较规则。
我们在创建和修改列定义的时候可以指定该列的字符集和比较规则,语法如下:
CREATE TABLE 表名(
列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],
其他列...
);
ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];
注意:
在转换列的字符集时需要注意,如果转换前列中存储的数据不能用转换后的字符集进行表示会发生错误。
3.1.5
仅修改字符集或仅修改比较规则
由于字符集和比较规则是互相有联系的,如果我们只修改了字符集,比较规则也会跟着变化,如果只修改了比较 规则,字符集也会跟着变化,具体规则如下:
只修改字符集,则比较规则将变为修改后的字符集默认的比较规则。
只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。
不论哪个级别的字符集和比较规则,这两条规则都适用
3.1.6
各级别字符集和比较规则小结
这4
个级别字符集和比较规则的联系如下:
如果创建或修改列时没有显式的指定字符集和比较规则,则该列默认用表的字符集和比较规则
如果创建或修改表时没有显式的指定字符集和比较规则,则该表默认用数据库的字符集和比较规则
如果创建或修改数据库时没有显式的指定字符集和比较规则,则该数据库默认用服务器的字符集和比较规则
3.2
客户端和服务器通信中的字符集
3.2.1
字符集转换的概念
如果接收 0xE68891
这个字节串的程序按照
utf8
字符集进行解码,然后又把它按照
gbk 字符集进行编码,最后 编码后的字节串就是
0xCED2
,我们把这个过程称为
字符集的转换
,也就是字符串
'我'
从
utf8 字符集转换为 gbk
字符集。
3.2.2 MySQL
中字符集的转换
从客户端发往服务器的请求本质上就是一个字符串,服务器向客户端返回的结果本质上也是一个字符串,而字符串其实是使用某种字符集编码的二进制数据。这个字符串可不是使用一种字符集的编码方式一条道走到黑的,从发送请求到返回结果这个过程中伴随着多次字符集的转换,在这个过程中会用到3
个系统变量:
数据传输过程: