05-MySQL--中文数据问题+校对集+乱码问题

一、中文数据问题

1、中文数据问题本质是字符集问题(客户端和服务器的字符集不同,而服务器的字符集是可以改变的)

2、计算机只识别二进制,人类更多是识别符号(字符)。需要有一个二进制与字符的对应关系(字符集)

注:

(1)字符集:二进制与字符的对应关系

(2)字符在计算机中对应的二进制码叫做字符编码(计算机有一个特点:只能存储对应的二进制码)

(4)字符 <--> 字符集 <--> 字符编码(二进制)

(5)字符在系统中都有对应的二进制在存储

3、如果直接通过cmd下的mysql.exe进行中文数据插入,可能会出错。出错原因如下:

(1)用户是通过客户端mysql.exe来操作mysqld.exe

(2)真正的SQL执行是服务器mysqld.exe来执行

(3)mysql.exe将数据传入mysqld.exe的时候,没有告知其对应的符号规则(字符集),而mysqld.exe也没有能力自己判断,就会使用自己默认的字符集

注:mysqld.exe默认的字符集是安装数据库时指定的,与创建数据库和数据表时指定的字符集无关。通过 show variables like 'character_set%'; 查看

4、解决方案:mysql.exe客户端在进行数据操作之前将自己所使用的字符集告诉mysqld.exe(cmd下的mysql.exe默认都只有一个字符集:GBK)

5、客户端向服务器插入中文数据没有成功,是因为在当前编码(字符集)下,对应的二进制编码转换成的十六进制是:一个汉字 <--> 两个字节(GBK)。而服务器认为接收数据的字符集是UTF8:一个汉字 <--> 三个字节,转换失败

注:GBK是两个字节读一次,UTF8是三个字节读一次

6、数据库服务器表现的一些特性,都是通过服务器端的变量来保存。系统先读取自己的变量,然后决定应该怎么表现

7、查看服务器识别的字符集

    -- 查看服务器识别的字符集
    show character set;

(1)服务器一共支持39种字符集

(2)基本上,服务器是万能的,什么字符集都支持

8、查看服务器默认的对外处理的字符集

    -- 查看服务器默认的对外处理的字符集
    show variables like 'character_set%';

9、服务器默认的接收客户端数据的字符集是utf8(安装数据库时指定的)

10、问题根源:客户端数据的字符集只能是GBK,而服务器接收客户端数据时,认为其字符集是utf8,产生矛盾

11、解决方案:改变服务器默认的接收客户端数据的字符集为GBK(客户端的不能改,所以只能修改服务器的字符集)

    -- 设置服务器默认的接收客户端数据的字符集
    set character_set_client = 字符集;

    -- 改变服务器默认的接收客户端数据的字符集为GBK
    set character_set_client = GBK;

12、插入中文数据成功,但使用select查看数据时依旧乱码

注:只设置character_set_client,就可以插入数据(告诉服务端,客户端传入的数据是gbk,服务器就会自动去处理了)。但只设置character_set_client,查询时会出现乱码

13、原因:返回时,数据来源是服务器,解析数据是客户端。客户端只识别GBK(一个汉字 <--> 两个字节),但服务器返回给客户端的数据是utf8(一个汉字 <--> 三个字节),客户端解析不了,导致显示时乱码

14、解决方案:修改服务器返回给客户端的数据的字符集为GBK

    -- 设置服务器返回给客户端的数据的字符集
    set character_set_results = 字符集;

    -- 修改服务器返回给客户端的数据的字符集为GBK
    set character_set_results = GBK;

15、set 变量 = 值; 的这种修改是会话级别的。即 当前客户端、当次连接有效,关闭失效

16、设置服务器对客户端的字符集,可以使用快捷方式:set names 字符集;

    -- 设置服务器对客户端的字符集的快捷方式
    set names 字符集;

    -- 等效于
    set character_set_client = 字符集;
    set character_set_results = 字符集;
    set character_set_connection = 字符集;    -- 连接层字符集

注:connection连接层,只是为了更方便客户端与服务端进行字符集转换而设,是字符集转变的中间者。如果统一了效率会更高,不统一也没问题

17、mysql.exe与mysqld.exe之间的处理关系一共分为三层

(1)客户端传入数据给服务端(client):character_set_client -- 为了让服务器识别客户端传来的数据

(2)服务端返回数据给客户端(server):character_set_results(服务端返回的数据是结果results) -- 为了告诉客户端服务端返回的数据的字符集

(3)客户端与服务端之间的连接(connection):character_set_connection -- 更好的帮助客户端与服务端之间进行字符集转换

18、客户端的数据是gbk,服务器针对客户端(接收和发送)默认是utf8,服务器需要做转换。相当于:

(1)客户端向服务器插入数据时,需要指定字符集

(2)服务器返回给客户端数据时,也需要指定字符集

但服务器支持39种字符集,服务器想以怎样的字符集存储,不关客户端的事儿。我们在乎的是客户端给服务器数据时,服务器是否认识;服务器将数据返回给客户端时,客户端是否认识(客户端与服务端之间的通信,必须要通过一个统一的字符集才能保证彼此之间对于数据的识别)

二、校对集

1、校对集:数据比较的方式(数据中有一个对应的集合,按照某种指定的方式比较)

2、校对集较少使用,一般情况下默认不区分大小写(默认使用_ci)

3、校对集有三种格式

(1)_bin:binary,二进制比较。取出二进制位,一位一位的比较。区分大小写

(2)_cs:case sensitive,大小写敏感。区分大小写(较少使用)

(3)_ci:case insensitive,大小写不敏感。不区分大小写(默认使用_ci)

4、查看数据库所支持的校对集

    -- 查看数据库所支持的校对集
    show collation;

注:utf8不支持中文比较,gbk支持中文比较(gbk_chinese_ci)

5、校对集应用:只有当数据产生比较的时候,校对集才会生效

6、每个数据库都有自己的校对集,在.opt文件中(保存数据的文件夹data --> 对应数据库名字的文件夹 --> .opt文件),里面保存了库选项(字符集和校对集)

    -- .opt文件中的内容
    default-character-set=gbk
    default-collation=gbk_chinese_ci    -- 默认为_ci,不区分大小写

7、对比:使用utf8的_bin和_ci来验证不同的校对集的效果(utf8不支持_cs)

(1)创建不同校对集对应的表

    -- 使用不同的校对集创建表
    create table my_collate_bin(
        name char(1)
    )charset utf8 collate utf8_bin;

    create table my_collate_ci(
        name char(1)
    )charset utf8 collate utf8_general_ci;

(2)插入数据

    -- 插入数据
    insert into my_collate_bin values ('a'), ('A'), ('B'), ('b');
    insert into my_collate_ci values ('a'), ('A'), ('B'), ('b');

    -- 查看(结果是插入的顺序)
    select * from my_collate_bin;    -- 结果:a A B b
    select * from my_collate_ci;     -- 结果:a A B b

(3)比较。根据某个字段进行排序(order by)

    -- 根据某个字段进行排序:order by 字段名 [asc|desc]
    -- asc:升序,desc:降序。默认是升序asc
    -- 排序查找
    -- 区分大小写排序。结果:A B a b
    select * from my_collate_bin order by name;
    -- 不区分大小写排序。结果:a A B b
    select * from my_collate_ci order by name; 

8、校对集必须在没有数据之前声明好。如果有了数据,再进行校对集的修改,则修改无效

9、修改校对集

    -- 修改表选项(字符集、校对集、存储引擎)
    alter table 表名 表选项 [=] 值;

    -- 修改校对集
    -- 修改校对集前,首先要确保表中数据为空,否则修改无效
    alter table my_collate_ci collate=utf8_bin;
    alter table my_collate_ci collate=utf8_general_ci;

10、字符集与其默认对应的校对集

(1)字符集:gbk,校对集:gbk_chinese_ci

(2)字符集:utf8,校对集:utf8_general_ci

三、乱码问题

1、动态网站由三部分构成:浏览器、Apache服务器、数据库服务器。三个部分都有自己的字符集(中文),数据需要在三个部分之间来回传递,很容易产生乱码

2、如何解决乱码问题:统一编码(三码合一)。但我们只能控制服务器(Apache服务器和数据库服务器),浏览器是用户管理的,控制不了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值