查看字符集
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:服务器向客户端返回数据时使用的字符集
- 如果创建或修改列时没有显式的指定字符集和比较规则,则该列默认用表的字符集和比较规则
- 如果创建表时没有显式的指定字符集和比较规则,则该表默认用数据库的字符集和比较规则
- 如果创建数据库时没有显式的指定字符集和比较规则,则该数据库默认用服务器的字符集和比较规则
修改字符集
在Windows下改.ini
配置文件,Linux下改.cnf
。
改了配置文件要重启mysql服务。
systemctl restart mysqld
修改了字符集以后,在修改字符集之前创建的数据库和数据表的字符集不变,只更改之后创建的库和表。
已有库表字符集的变更
alter database db1 character set 'utf8'
alter table tb1 convert to character set 'utf8'
如果原有的数据是用非utf8编码的话,数据本身编码不会改变。已有的数据需要导出或者删除,然后重新插入。
各个级别的字符集
MySQL有4个级别的字符集和比较规则,分别是:
- 服务器级别
- 可以在配置文件改好了重启
- 在服务器运行中修改字符集,修改变量
- 数据库级别
- 表级别
列级别
- 建表时指定列级别的字符集和排序规则
- ALTER修改或者添加列级别的字符集和排序规则
字符集与比较规则
utf8和utf8mb4
utf8
字符集表示一个字符需要使用1-4个字节,但是我们常用的一些字符使用1-3个字节就可以表示了。而字符集表示一个字符所用的最大字节长度,在某方面会影响系统的存储和性能,所以设计MySQL的设计者定义了两个概念:
utf8mb3
:阉割过的utf8
字符集,只使用1-3字节表示字符utf8mb4
:正宗的utf8
字符集,使用1-4个字节表示字符
在MySQL中utf8
是utf8mb3
的别名,所以之后在MySQL中提到utf8就意味着使用1-3个字节来表示字符。
如果有使用4个字节编码一个字符的情况,比如存储一些emoji表情,就用utf8mb4
。
SHOW CHARSET;
#或者
SHOW CHARACTER SET;
比较规则
比较规则字符串格式:字符集名称_语言名称_发音大小写
比如utf8_polish_ci
表示以波兰语的规则比较,utf8_spanish_ci
是以西班牙语的规则比较,utf8_general_ci
是一种通用的比较规则。
后缀表示该比较规则是否区分语言中的重音,大小写。具体如下:
后缀 | 英文释义 | 描述 |
---|---|---|
_ai | accent insensitive | 不区分重音 |
_as | accent sensitive | 区分重音 |
_ci | case insensitive | 不区分大小写 |
_cs | case sensitive | 区分大小写 |
_bin | binary | 以二进制方式进行比较 |
查看字符集和比较规则
#查看某字符集的比较规则
SHOW COLLATION LIKE 'utf8%';
#查看服务器的字符集和比较规则
SHOW VARIABLES LIKE '%_server';
#查看数据库的字符集和比较规则
SHOW VARIABLES LIKE '%_database';
#查看具体数据库的字符集
SHOW CREATE DATABASE dbname;
#查看具体某表的字符集
SHOW CREATE TABLE tbname;
#查看具体某表的比较规则
SHOW TABLE STATUS FROM dbname LIKE '%tbname';
注意
:::success
utf8_unicode_ci和utf8_general_ci对中,英文来说没有实质性的区别。
utf8_general_ci校对速度快,但准确度稍差
utf8_unicode_ci准确定高,但校对速度稍慢。
一般情况,用utf8_general_ci就够了,但是如果你的应用有德语法语,或者俄语,请一定使用utf8_unicode_ci
:::
请求到响应过程中字符集的变化
我们知道从客户端发往服务器的请求本质上就是一个字符串,服务器向客户端返回的结果本质上也是一个字符串,而字符串其实就是使用某种字符编码的二进制数据。
这个字符串可不是使用一种字符集的编码方式一条道走到黑的,从发送请求到返回结果这个过程中伴随着多次字符集的转换,在这个过程中会用到3个系统变量,如下:
系统变量 | 描述 |
---|---|
character_set_client | 服务器解码请求使用的字符集 |
character_set_connection | 服务器处理请求时会把请求字符串从chararcter_set_client转为character_set_connection |
character_set_results | 服务器向客户端返回数据时使用的字符集 |
统一设置字符集
开发中我们通常把上面三个系统变量设置成和客户端使用的字符集一致的情况,这样减少了字符集转。用下面的语句统一设置
SET NAMES 字符集名称;
SET character_set_client = 字符集名称;
SET character_set_connection = 字符集名;
SET character_set_results = 字符集名;