这里写写对于MySQL字符集学习之后的一些认识,希望大家多多指正、补充。
一、首先什么是字符集呢?
字符集就是一组字符与符号编码的集合。简单的说就是自然语言的字符如何用二进制码来表示的对应关系的集合。可以理解为字符类型存储字符的格式。
三、查看数据库支持的字符集与校对规则所谓校对规则就是定义了字符集当中的字符如何进行比较的规则,这对于SQL中的字符条件会有影响。
show character set; #查看数据库支持的字符集,也可看到字符集对应的默认校对规则。
show collation like 'utf8%'; #查看UTF8字符集相关的校对规则,其中以_ci结尾的表示大小写不敏感校对,_cs结尾的表示大小写敏感校对
五、字符集与校对规则的设置,分两个层面进行设置:GB2312:中文双字节编码,也就是每个汉字用两个字节表示,只包含简体汉字与常用符号。
GBK:也是双字节编码,包含中日韩三国的字符,GB2312的超集。
BIG5:繁体中文字符集,GBK的子集。
UTF8:变长字符集,英文字符用一个字节编码,多字节字符都用三个字节编码,GBK的超集。
UTF8MB4:UTF8的超集,相对于UTF8新增对emoji表情字符等特殊字符的支持(5.5版本之后开始引入)。
1、设置连接数据库执行操作时使用的字符集
a、查看当前客户端的字符集
show global variables like '%client'; #全局设置
show variables like '%client'; #当前会话设置
b、客户端字符集的作用过程
SQL语句(字符集为character_set_client) ==> 服务端接受到SQL,转换字符集为character_set_connection,然后处理SQL并使用collation_connection指定的校对规则处理语句条件中的字符比较(注意不是列的比较排序) ==> 按照字符集character_set_results返回结果。
c、修改连接相关的字符集
set names方式
set names 'chaset_name' [collate 'collation_name']; <==> set character_set_client=; set character_set_connection=; set character_set_results=;
set character set方式
set character set 'chaset_name'; <==> set character_set_client=; set character_set_results=; 另外两个connection相关的参数继承全局设置
2、设置数据库存储数据时使用的字符集
a、查看服务端全局字符集、校对规则设置(不做更细粒度设置默认使用该设置)
b、全局修改服务端字符集、校对规则(即使是全局参数修改,不手动写入参数文件的话下次服务重启之后仍然失效)show global variables like '%server';
修改全局字符集、校对规则
set global character_set_server=utf8mb4;
修改会话字符集、校对规则
set session character_set_server=utf8;
show session variables like '%server'; #确认是否修改成功
c、数据库级别的字符集、校对规则设置(还记得上面创建库时在目录下生成的文件db.opt吗?存储于该文件中)
创建数据库时指定
create database database_name charset(character set) utf8 collate utf8_general_ci;
create database database_name charset(character set) utf8; #collation缺省时继承charset的默认校对规则(show collation可查)
create database database_name collate utf8_general_ci; #charset缺省时默认为collation所属的字符集
使用alter database进行设置
alter database database_name charset utf8mb4;
d、表级别字符集设置,创建表时指定(缺省继承数据库的设置)
create table table_name (col_name col_type, ..) charset utf8;
e、列级别字符集设置(缺省继承表的设置)
create table table_name(col_name varchar charset gbk);
六、字符集是不要轻易修改的,修改数据库存储时使用的字符集对现有数据的影响如下:
1、全局、库级别的字符集修改
对现有数据没有影响,只影响修改之后进行存储的数据;
2、表、列级别的字符集修改
把子集改成超集对数据没有影响,因为超集支持子集的所有字符,比如:lartin1 --> gb2312 --> gbk --> utf8 --> utf8mb4
把超集改成子集则有可能丢失数据,一旦存在不支持的字符则无法正确编码存储而丢失数据。