- 字符集
- 比较规则
- 命名含义
- 服务端设置
- 服务器级别
- 数据库级别
- 表级别
- 列级别
- 客户端通信设置
- 字符集转换
- 相关配置
- 服务端和客户端通信过程中的编解码
- 使用
show charset [like ..];
查看支持的字符集 - 使用
show collation [like ..];
查看比较规则 - 常用 utf8(utf8mb3) 和 utf8mb4(mysql8 默认)
字符集
字符集包含了两层意思:编码和存储规则(😂 两个名次可能表述不准确,意思理解到了就成),类似于接口和具体的实现,编码规定了字符集的范围边界,指定字符集含有哪些字符,给所有字符一个编号,而存储规则是实现,用来规定在传输存储时将怎样存储
- 对于小字符集,如 ascii,iso8859-1 等,只需要一个字节就能表示的,编码和存储规则是统一的
- 对于大字符集,尤其是常用的 unicode 字符集,有多种存储规则的实现,如 utf8,utf16,utf32 等,多种实现各自擅长不同的工作,如 utf8 没有字节序的问题,变长节省空间,方便传输等,但是处理显示的时候比较费劲(二进制处理成字符显示),utf16 就比较轻松,但是会有字节序,存储空间大的问题。
具体在 mysql 中也是一样的,一般使用 utf8mb4 就完事了,啥符号都能存储,而 utf8mb3(也就是 utf8) 是一个残疾版,最大只有三个字节,所以没有实现所有的 unicode 符号(如一些 emoji 表情就存不了,但是也不是不能存,可以在存之前转换一下嘛),但是节省空间,看选择了。
其实对于编码这一块,不单单局限于字符,所有显示和二进制有出入的都是编码,文件,数字,影音,都是。
cc 还有一篇简单介绍编码的文章 《数据背后的二进制》
比较规则
命名含义
- 字符集 + 语言 + 区别大小写
- 如 utf8_spanish_ci: utf8 字符集,用于西班牙语,不区分大小写
general 表示通用
后缀 | 英文释义 | 描述 |
_ai | accent insensitive | 不区分重音 |
_as | accent sensitive | 区分重音 |
_ci | case insensitive | 不区分大小写 |
_cs | case sensitive | 区分大小写 |
_bin | binary | 以二进制方式比较 |
每种字符集对应若干种比较规则,每种字符集都有一种默认的比较规则, SHOW COLLATION 的返回结果中的 Default 列的值为 YES 的就是该字符集的默认比较规则,比方说 utf8 字符集默认的比较规则就是 utf8_general_ci
服务端设置
有四个设置等级,每个等级都可以单独设置字符集和比较规则,单独修改哪一个都会自动修改另一个,如单独修改字符集,则会自动修改比较规则为相应字符集的默认比较规则(可以在 show charset; 中看到默认的比较规则),而单独修改比较规则,则会自动修改为对应的字符集
服务器级别
- 配置项
- character_set_server
- collation_server
- 默认为 utf8mb3 (mysql8 为 utf8mb4)
数据库级别
- 配置项
这两个配置是只读的,修改无效,只能用 alert database 来修改库的字符集
并且如果没有选择库直接查看,则和服务器字符集一样
- character_set_database
- collation_database
- 创建库时指定或后期修改
- default 写不写都一样
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 比较规则名称];
- 默认和所在表的字符集相同
客户端通信设置
字符集转换
转换是以字符为基础的
- 二进制 -> 字符 :解码
- 字符 -> 二进制 :编码
相关配置
系统变量 | 描述 |
character_set_client | 服务器解码请求时使用的字符集 |
character_set_connection | 服务器处理请求时会把请求字符串从 character_set_client 转为 character_set_connection |
character_set_results | 服务器向客户端返回数据时使用的字符集 |
由于这三个没必要设置成不同的,往往设置和客户端编码一致,所以 mysql 提供了快捷设置
set names <charset>
,同时设置这三个编码客户端可以使用启动项 default-character-set= 来设置这三个值,效果和
set names <charset>
一样
服务端和客户端通信过程中的编解码