彻底告别mysql乱码(mysql字符集详解)
用到的指令
# 查看变量
show [GLOBAL|SESSION(LOCAL)] variables [LIKE 匹配内容];
# 修改变量
set [GLOBAL|SESSION(LOCAL)] varable_name=value;
涉及系统变量
character_set_client
将客户端请求内容,通过该变量指定的字符集进行解码
character_set_connection
将解码结果按指定字符集进行编码,编码结果用于服务器处理
character_set_results
服务器向客户端返回数据时使用的字符集
案例说明
用一个简单查询举例:select * from student where name = '郁‘;
案例环境
表结构及内容
CREATE TABLE student(
name VARCHAR(10) CHARACTER SET chat_y;
)
insert into student(name) value ("郁");
insert into student(name) value ("我");
变量值
- character_set_client=chat_w;
- character_set_connection=chat_y;
- character_set_results=chat_z;
字符集
chat_y
字符 | 字节 |
---|---|
郁 | 1 |
我 | 2 |
chat_w
字符 | 字节 |
---|---|
我 | 1 |
郁 | 2 |
chat_z
字符 | 字节 |
---|---|
我 | 3 |
执行过程
- 客户端输入指令。
指令编码成二进制串,传递至服务端(这里我们假设客户端采用的字符集为chat_y,所以"郁"对应的编码为"1") - 服务端接收请求。
此时用到的变量为“character_set_client”,值为“chat_w”。经过解码,我们的查询语句就变成了"select * from student where name = “我”。 - 服务端处理请求。
此时用到的变量为“character_set_connection”,值为“chat_y”。将“我”进行编码,结果为“2”。
而我们的表中,name列的字符集被指定为“chat_y"。所以,"郁"经过编码,结果为“1”;所以,"我"经过编码,结果为“2”。
最终,会将“我”这一列返回。 - 服务端返回结果。
此时用到的变量为“character_set_results”,值为“chat_z”。“我”经过编码,结果为“3”。而“3”在“chat_y”中不存在对应的映射,计算机不知道该展示什么,最后到了我们眼中,就变成了乱码。
补充
# 该指令能同时修改上述3个变量
SET NAMES 字符集名;
参考
《MySQL 是怎样运行的:从根儿上理解 MySQL》 --小孩子