3.1字符集和比较规则
3.1.1字符集简介
字符集主要包含如下三个方面:
- 界定字符范围:即将哪些字符编码
- 编码:将字符映射成二进制数
- 解码:将二进制数映射成字符
3.1.2比较规则简介
即比较字符的大小,常见的的有直接比较字符的二进制编码的大小以及区分大小写的比较字符二进制编码的大小等。
3.1.3一些重要的字符集
字符集 | 简介 |
---|---|
ASSIC | 收录128个字符,用1个字节编码 |
ISO 8859-1 | 在ASSIC的基础上增加到了256个字符,用1个字节编码 |
GBK | 其中收录了汉字,并且如果字符在ASSIC的范围内用1个字节编码,否则用2个字节编码 |
UTF-8 | 收录汉字,并且采用变长编码,其中一般为1-4个字节,并且汉字为3个字节 |
3.2MySQL中支持的字符集和比较规则
3.2.1MySQL中的utf8和utfmb4
其中utf8一般默认指的是utf8mb3,其中utfmb3一般用1-3个字节编码,而utfmb4用1-4个字节编码,如果要存储表情符号需要用utfmb4,并且Mysql8.0中默认字符集为utfmb4。
3.2.2字符集的查看
show charset like ''
查看结果如上图所示,可以看出charset都是用小写表示的,并且注意此时查看的是mysql支持的字符集。
3.2.3比较规则的查看
show collation like ''
其中查询结果如上图所示:
并且collation的含义是比较规则,其命名为:”需要比较的字符集名_比较规则所用的语言__是否区分大小写/重音“等,如上面的utf8_general_ci表示以通用的语言比较,并且不区分大小写。而且default为yes表示为该字符集默认的比较规则。
3.3字符集和比较规则的应用
3.3.1各级别的字符集和比较规则
其中数据库的字符集和比较规则分为4个级别,分为服务器级别,数据库级别,表级别,列级别。
1、服务器级别
查看:
SHOW VARIABLES LIKE 'character_set_server'
show VARIABLES LIKE 'collation_server'
修改:
也可以直接修改系统变量
character_set_server=latin1
2、数据库级别
查看:
SHOW VARIABLES LIKE 'character_set_database'
修改:包括在创建数据库时修改或者直接修改
CREATE DATABASE test_charset
CHARSET utf8
ALTER DATABASE test_charset
CHARSET gbk
注意:
1、此时character_set_database和character_set_database都是只能查看的系统变量,不能通过直接赋值对系统变量修改。
2、并且查看某个数据库的字符集以及比较规则时,需要use到该数据库中。当为指定数据库的字符集时,默认采用server的字符集以及比较规则。
3、表级别
修改:包括在创建表时修改或者直接修改
CREATE TABLE test_charset_table(
id INT(10)
)CHARSET utf8 COLLATION utf8_general_ci;
以及
ALTER TABLE test_charset_table CHARSET utf8
注意:如果没有指定便采用对应database的字符集。
4、列级别
修改:包括创建表时以及修改
create table 表名(
列名 字符串类型 charset 字符串名称 collation 比较规则名称,
);
直接修改:
alter table 表名 modify column 列名 列类型(占的字节数) charset 字符串名称 collation 比较规则名称
注意:当列未指定字符集时,默认采用表级别的字符集以及比较规则,并且当修改列的字符集时如果不支持列中内容则会报错,如列中为‘奥’,但是如果将字符集变为ASCII便会出错。
5、字符集以及比较规则关系
- 当只修改字符集时,比较规则会采用该字符集默认的。
- 当修改比较规则时,字符集会采用该比较规则对应的字符集。
3.3.2客户端与服务器通信过程中使用的字符集
如果编码和解码中使用的字符集不同会导致乱码问题,并且字符集转换表示比如一个才程序将某个字节序列如0Xe68891利用UTF-8解码成字符,然后再用gbk进行编码,此时便完成了UTF-8到GBK的转换。
对于客户端与服务器通信时字符集转换过程如下:
注意:
-
对于步骤1,当客户端向服务器发送请求的时候,会默认采用系统默认的字符集对请求编码,对于类UNIX系统,可以通过echo $LC_ALL 或者echo $LC_CTYPE或者echo $LANG查看默认的字符集,其中优先级为从高到低;对于windows,采用代码页的形式,并且chcp查看,如果是936表示是gbk,并且如果启动项设置了default-character-set,便使用该字符集作为客户端的默认字符集并对请求编码。
-
对于步骤2,服务器收到请求时,会默认为客户端采用的是character_set_client的字符集进行编码的,也会用该字符集对客户端的字符集解码。
-
对于步骤3,服务器将都收到的请求转化为以character_set_connection编码的字节序列,即会将character_set_client的字符集转化为character_set_connection的字符集,所以对于服务器中的比较规则时以 character_set_connection为准的。
-
对于列有单独的字符集的时候,其优先级最高,其他的数据需要转化为列对应的字符集以及比较规则进行比较。
-
其中character_set_client为服务器认为客户端对请求编码的字符集,character_set_connection为在服务器中最后将请求编码的字符集,character_set_result为客户端返回响应编码的字符集。他们都是系统变量,可以修改,并且也可以通过“set NAMES 字符集名”统一修该,但是不会修该客户端的默认字符集。
3.3.3比较规则的应用
一般排序时是按照比较规则排序的,如果排序结果不对,首先考虑比较规则是否设置合理。