字符集是指一种从二进制编码到某类字符符号的映射。
校对是一组用于某个字符集的排序规则。
每一类编码字符都有其对应的字符集和校对规则,mysql对各种字符集的支付非常完善,但也带来
了一定的复杂性,某些场合下甚至会牺牲一定的性能
mysql如何使用字符集
每种字符集都可能有多种校对规则,并且都有一个默认的校对规则,每个校对规则都是针对某个特定的
字符集的,和其它字符集没有关系,校对规则和字符集总是一起使用,所以这样的组合称为一个字符集。
mysql有很多选项用于控制字符集,这些选项和字符集很容易混淆
只有基于字符的集,才有真正字符的概念,对于其它类型的值,字符集
只是一个设置,指定用哪一种字符集来做比较或其他操作。
基于字符的值,能存放在某列中,查询的字符串中,表达式的计算结果中或者用户的变量中,等等。
mysql的设置可分2类:创建对象时的默认值,在服务器和客户端通信时候的设置。
创建对象时候的默认设置
mysql服务器有默认的校对规则和字符集,每个数据库也有自己的默认值,每个表也有自己的默认值
这是一个逐层继承的默认设置,最终靠底层的默认设置将影响你创建的对象。这些默认值将至上而下的
告诉MYSQL应该使用什么字符集来存储某个列。
在迁移mysql数据库时候出现了乱码问题
![](https://i-blog.csdnimg.cn/blog_migrate/480abb29181d0aed77436bfcc255a42b.png)
下面我们就来分析乱码的原因
1,首先我们查看到mysql默认配置的字符集编码
![](https://i-blog.csdnimg.cn/blog_migrate/10cc23cd8178e7e8505180e55f3f08b9.png)
我们可以看到
character_set_client 为client端使用的字符集编码
character_set_connection 为从客户端收到数据,在建立连使用的字符集编码
character_set_database 为默认数据库使用的字符集编码(无论默认数据库如何改变都使用该字符集,
若没有默认数据,则使用character_set_server指定的字符集编码,该字符集为系统自定义,建议勿改 )
character_set_results 为结果集的字符集
character_set_server 为数据库服务器的默认字符集,
(character_set_database的设置和默认数据库设置相同,当改变默认数据库的时候
该值也会变,所以当连接到mysql又没有指定要使用的数据库时,默认值会和character_set_server相同)
character_set_system为存储系统元数据的字符集,该值总是utf8,不需要设置
其中元数据定义为数据的数据,为数据及信息资源的描述性信息,主要用来描述数据属性
在mysql至上而下的存储阶梯中,的每一层,都可以指定字符集或者使用服务器默认的字符集
1,创建数据库的时候,将根据服务器上的character_set_server来指定该数据的默认字符集
2,创建表的时候,将根据数据库的字符集来设置指定这个表的字符集设置。
3,创建列的时候,将根据表的设置指定列的字符集设置。
![](https://i-blog.csdnimg.cn/blog_migrate/90d3ad235124d638f20c75ceec5ab6ea.png)
需要注意的是,真正存放数据的是列,所以更高级的阶梯设置的只是指定默认值,一个表的默认字符集
设置无法影响存储在这个表中某个列的值,只有当创建而未给列指定字符集的时候,表的默认字符集才
起作用。
服务和客户端通信时候的设置
当服务器和client端通信的时候,他们可能使用不同的字符集,这时候服务器必将进行翻译转换的工作。
1,服务器总是假设client是按照character_set_client设置的字符来传输数据和SQL语句。
2,当服务器收到client端的sql语句时,它先将其转成字符集character_set_connection。它还使用这个
设置来决定如何将数据转成字符串。
3,当服务器返回数据或错误消息给client时,它会将其转换成character_set_result。
由以上的知识做铺垫,我们可以为产生乱码的原因做一个总结
1,client端没正确设置client字符集,导致原sql语句被转换成了connection所
指定的字符集,这种转换可能是会丢失信息的同时我们也应该在意的是做数据库
迁移,导出导入数据库时候的编码格式,如果如果client端是utf8,connection使用
的是gb2312那么在这个转换过程中必然会导致数据丢失,反之则不会,一定要保证
connection的字符集大于client字符集才能保证转换信息不被丢失
2,用户程序文件使用的编码方式,用户程序和数据库的连接方式,所以不单单是数据库
存储问题
好了,知道了意思几点,我们可以相对应的查询文件和配置的相关代码
我们可以在编译的时候指定以上所示的几个字符集,也可以通过修改配置文件达到这个目的
1.在[mysqld]下添加
character-set-server=utf8
2.在[client]下添加
default-character-set=utf8
character-set-server=utf8
2.在[client]下添加
default-character-set=utf8
此时我们建数据库时候不需指定utf8字符集了,但是此种方式解决了服务器的字符集存储和
校对问题,但是对客户端的连接是无用的,客户端此时一般要指明utf8才能避免乱码
有一条命令set names utf8是对应服务器以下几个命令的
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
但这几条命令在配置文件中不能设置,只能在sql命令行下输入
故需在[mysqld]下添加:
init_connect = 'SET NAMES utf8'
init_connect = 'SET NAMES utf8'
进入mysql show 一下字符集
![](https://i-blog.csdnimg.cn/blog_migrate/9a861a100c8caa82621bbcb3488f8a7a.png)