字符集
- 简介
在MySQL 8.0版本之前,默认字符集为 latin1 ,utf8字符集指向的是 utf8mb3 。网站开发人员在数据库设计的时候往往会将编码修改为utf8字符集。如果遗忘修改默认的编码,就会出现乱码的问题。从MySQL8.0开始,数据库的默认编码将改为 utf8mb4 ,从而避免上述乱码的问题
- 查看字符集
# 方式1
show variables like 'character%';
# 方式2
show variables like '%char%';
- 修改字符集
vim /etc/my.cnf
character_set_server=utf8
# 重启mysql
systemctl restart mysqld
- 修改已创建数据库的字符集
alter database dbtest1 character set 'utf8';
- 修改已创建数据表的字符集
alter table t_emp convert to character set 'utf8';
- 字符集级别
服务器级别
数据库级别
表级别
列级别
- 查看
show variables like 'character%';
character_set_server:服务器级别的字符集
character_set_database:当前数据库的字符集
character_set_client:服务器解码请求时使用的字符集
character_set_connection:服务器处理请求时会把请求字符串从character_set_client转为
character_set_connection
character_set_results:服务器向客户端返回数据时使用的字符集
- character_set_server
# 服务器级别的字符集
# 配置方式1,修改配置文件,当服务器启动的时候读取这个配置文件后这两个系统变量的值便修改了
[server]
character_set_server=gbk # 默认字符集
collation_server=gbk_chinese_ci #对应的默认的比较规则
# 配置方式2:在服务器程序运行过程中使用 SET 语句修改以上两个变量的值
- character_set_database
# 当前数据库的字符集
# 在创建和修改数据库的时候可以指定该数据库的字符集和比较规则
CREATE DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
ALTER DATABASE 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
- 表级别
# 可以在创建和修改表的时候指定表的字符集和比较规则
CREATE TABLE 表名 (列的信息)
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]]
ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 字符集名称]
[COLLATE 比较规则名称]
# 如果创建和修改表的语句中没有指明字符集和比较规则,将使用该表所在数据库的字符集和比较规则作为该表的字符集和比较规则
- 列级别
对于存储字符串的列,同一个表中的不同的列也可以有不同的字符集和比较规则。我们在创建和修改列定义的时候可以指定该列的字符集和比较规则
CREATE TABLE 表名(
列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],
其他列...
);
ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];
# 对于某个列来说,如果在创建和修改的语句中没有指明字符集和比较规则,将使用该列所在表的字符集和比较规则作为该列的字符集和比较规则
- 总结
如果 创建或修改列 时没有显式的指定字符集和比较规则,则该列 默认用表的 字符集和比较规则
如果 创建表时 没有显式的指定字符集和比较规则,则该表 默认用数据库的 字符集和比较规则
如果 创建数据库时 没有显式的指定字符集和比较规则,则该数据库 默认用服务器的 字符集和比较规则
- utf8 与 utf8mb4
utf8 字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而字符集表示一个字符所用的最大字节长度,在某些方面会影响系统的存储和性能,所以设计
MySQL的设计者偷偷的定义了两个概念:
utf8mb3 :阉割过的 utf8 字符集,只使用1~3个字节表示字符
utf8mb4 :正宗的 utf8 字符集,使用1~4个字节表示字符
- 比较规则
MySQL版本一共支持41种字符集,其中的 Default collation 列表示这种字符集中一种默认的比较规则,里面包含着该比较规则主要作用于哪种语言,比如 utf8_polish_ci 表示以波兰语的规则
比较, utf8_spanish_ci 是以西班牙语的规则比较, utf8_general_ci 是一种通用的比较规则
- 常用操作
#查看GBK字符集的比较规则
SHOW COLLATION LIKE 'gbk%';
#查看UTF-8字符集的比较规则
SHOW COLLATION LIKE 'utf8%';
#查看服务器的字符集和比较规则
SHOW VARIABLES LIKE '%_server';
#查看数据库的字符集和比较规则
SHOW VARIABLES LIKE '%_database';
#查看具体数据库的字符集
SHOW CREATE DATABASE dbtest1;
#修改具体数据库的字符集
ALTER DATABASE dbtest1 DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
#查看表的字符集
show create table employees;
#查看表的比较规则
show table status from atguigudb like 'employees';
#修改表的字符集和比较规则
ALTER TABLE emp1 DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
-
请求到响应过程中字符集的变化
-
案例1
# 设置字符集
set character_set_connection = gbk;
# 查询某个字符
SELECT * FROM t WHERE s = '我';
# 客户端发送请求所使用的字符集,当客户端使用的是 utf8 字符集,字符 '我' 在发送给服务器的请求中的字节形式就是:0xE68891
# 服务器接收到客户端发送来的请求其实是一串二进制的字节,它会认为这串字节采用的字符集是character_set_client ,然后把这串字节转换为 character_set_connection 字符集编码的
字符
# 由于计算机上 character_set_client 的值是 utf8 ,首先会按照 utf8 字符集对字节串0xE68891 进行解码,得到的字符串就是 '我' ,然后按照 character_set_connection 代表的
字符集,也就是 gbk 进行编码,得到的结果就是字节串 0xCED2
# 因为表 t 的列 col 采用的是 gbk 字符集,与 character_set_connection 一致,所以直接到列中找字节值为 0xCED2 的记录,最后找到了一条记录
# 上一步骤找到的记录中的 col 列其实是一个字节串 0xCED2 , col 列是采用 gbk 进行编码的,所以首先会将这个字节串使用 gbk 进行解码,得到字符串 '我' ,然后再把这个字符串使用
character_set_results 代表的字符集,也就是 utf8 进行编码,得到了新的字节串:0xE68891 ,然后发送给客户端
# 由于客户端是用的字符集是 utf8 ,所以可以顺利的将 0xE68891 解释成字符 我 ,从而显示到我们的显示器上,所以我们人类也读懂了返回的结果