# MySQL 中文乱码

为了能在数据库中存储中文数据并确保不会出现中文乱码错误,通常我们需要将字符集设置为 utf8 ,或其它支持中文的字符集。

MySQL 的默认字符集 latin1 是不支持中文的。

# 1. 查看字符编码

通过 MySQL 客户端连接到 MySQL 服务器后,执行如下命令:

show variables like '%char%';

在显示的表格状的结果中,表现出有三项配置的值是 latin1(或其它) 。它们分别是:

# 配置项
1 character_set_client
2 character_set_connection
3 character_set_results

我们最终的目的是需要将它们三项和其它的配置一样,改为 utf8

注意,上述表格装的结果中,『并不是』说所有项目都必须为 utf8 。其中,character_set_filesystem 的值为 binarycharacter_sets_dir 的值是一个路径。这两项本应如此,不需要动它们。

# 2. 修改方案

# 2.1 方案一:my.ini 配置文件

my.ini 文件是 MySQL 的配置文件。MySQL 服务器启动时会从中读取相关配置。如果这个配置文件不存在,或者配置文件中未明确标识的配置项,MySQL 就是用默认配置。很显然 latin1 就是上述三个配置项的默认值。

无论是在安装版还是在解压版的 MySQL 中,my.ini 文件都是在 MySQL 的家目录下。

打开并编辑 my.ini 配置文件:

  • [mysql] 配置段下添加 default-character-set=utf8

  • [mysqld] 配置段下添加 character_set_server=utf8

需要注意的有两点:

  1. 只需要添加这两个配置,就能影响之前所说的三项配置。

  2. 在早期的 MySQL 版本中,[mysqld] 配置段下添加的本来和 [mysql] 一样,也是 defalt-character-set=utf8 。不过,后来的 MySQL 版本中将的这个配置的名字改了。

my.ini 添加了这两项配置后,重启 MySQL 服务,再在 MySQL 客户端中执行 show variables like '%char%'; 命令,你会发现之前所说的三项值从 latin1 变为了 utf8

这个方案有一个问题,你可能没有权限修改 my.ini 文件,或无法取修改 my.ini 文件!

这种情况下,你即便知道要将 my.ini 中修改成 xxx 样子,就能修改字符集编码,但是你也无能为力。这种情况下,你需要使用下面这种方案。

# 2.2 方案二:在建库时指定表的字符集

my.ini 中的这些配置都是默认配置,在创建数据库( create database )时,如果你指定了 database 的字符集,那么 MySQL 就以你的建库语句中所指定的字符集为准,而非 my.ini 的默认配置。

CREATE DATABASE <库名>
    DEFAULT CHARACTER SET utf8   -- 设置字符集
    ...其它设置
;

一个良好的习惯是,不要依赖于 my.ini 的设置,在你提供的建库语句中老老实实加上字符集设置!

一个良好的习惯是,不要依赖于 my.ini 的设置,在你提供的建库语句中老老实实加上字符集设置!

一个良好的习惯是,不要依赖于 my.ini 的设置,在你提供的建库语句中老老实实加上字符集设置!

# 2.3 方案三:通过 SQL 命令修改

这是你在『最倒霉』的情况下要使用的方案,你『倒霉』在 2 点:

  1. 你没有权限,或无法修改 my.ini 配置文件的内容。即,方案一不可行

  2. databse 不是你建的,而且已经建好了,“当年”建库时没有指定 utf8 字符集,现在,你又不能删库重建。即,方案二不可能。

当然,一般情况下你不可能这么倒霉,或者说,真遇到了这种情况,那就意味着之前的某些工作出了问题,可以调整、修正,而不是靠你在这里曲线救国。

在 SQL 命令行中依次输入三条(与上述三个配置对应的)命令:

set character_set_client=utf8;
set character_set_connection=utf8;
set character_set_results=utf8;

再次执行 show variables like '%char%'; 命令,你会发现这三个配置已经变为了 utf8

但是,当你退出 MySQL 客户端再重新连接到 MySQL 服务器时,你会发现这三项配置又变回来了!这是因为通过 SQL 命令的修改只对本次连接/会话有效。因此这种方法基本上没用。

这种情况下,你本次连接中向 MySQL 的表中加入、修改的字符数据会被 MySQL 以 utf8 方式存储,而无视 my.ini 和建库语句中的字符集设置。