
1.4 MySQL数据库中数据表乱码解决方法
在研究安全技术的过程中,需要花很多时间跟数据库打交道,而如果数据库中的数据“不听话”,就会引起大麻烦。相信很多读者朋友都曾遇到数据库中的数据出现乱码的情况。研究发现,其原因通常是在字符集设置过程中出现了问题。
1.4.1 字符集基础知识
字符值包括字母、数字和特殊符号。在存储字符值之前,必须将字母、数字和特殊符号转换为数值代码。所以,必须建立一个转换表,其中包含每个相关字符的数值代码。这样的转换表称为字符集,有时也称为代码字符集(Code Character Set)或字符编码(Character Encoding)。
要想让计算机处理字符,不仅需要考虑从字符到数值的映射,还需要考虑如何存储这些数值,所以就诞生了编码方案的概念。是定长存储还是变长存储?是用一个字节还是用多个字节?仁者见仁,智者见智。根据不同的需要,产生了很多编码方案。例如,对于Unicode,就存在UTF-8、UTF-16、UTF-32。而在MySQL中,字符集的概念和编码方案的概念被作为同义词看待,一个字符集(Character Set)是由一个转换表和一个编码方案组合而成的。Collation(校对)的概念是为了解决排序和分组问题提出的——在字符的排序和分组过程中需要比较字符,而Collation定义了字符的大小关系。
MySQL的字符集支持(Character Set Support)包括字符集和排序方式两个方面,对字符集的支持细化到服务器(Server)、数据库(Database)、数据表(Table)、连接(Connection)四个层次。
1.MySQL默认字符集
MySQL对于字符集的指定可以细化到一个数据库、一张表、一列应该用什么字符集。
· 在编译MySQL时,会指定一个默认的字符集。这个字符集是latin1。
· 在安装 MySQL 时,可以在配置文件 my.ini 中指定一个默认的字符集。如果没有指定,就继承在编译时指定的值。
· 启动mysqld守护进程时,可以在命令行参数中指定一个默认的字符集。如果没有指定,就继承配置文件中的值,此时character_set_server被设置为默认字符集。
· 在创建一个新的数据库时,除非明确指定,这个数据库的字符集默认被设置为 character_set_server。
· 当选定一个数据库时,character_set_database被设置为这个数据库的默认字符集。
· 当在这个数据库里创建一张表时,此表的默认字符集被设置为character_set_database(也就是这个数据库的默认字符集)。
· 当在表内设置一列时,除非明确指定,此列的默认字符集就是表的默认字符集。
如果采用默认设置,那么所有数据库中的所有表的所有列都用latin1存储。不过,在安装MySQL时一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为UTF-8,这保证了在默认情况下所有数据库的所有表的所有列都使用UTF-8进行存储。
2.查看默认字符集
查看系统的字符集和排序方式,可以通过下面两条命令实现。

3.修改默认字符集
修改默认字符集,最简单的方法就是修改MySQL的my.ini文件中的字符集键值,示例如下。

修改后,重启MySQL服务,示例如下。

执行“mysql>SHOW VARIABLES LIKE'character%';”命令,发现数据库编码已经是UTF-8了。
还有一种修改字符集的方法,就是使用执行MySQL命令,示例如下。

4.在Linux中修改和查看MySQL数据库的字符集
查找MySQL的cnf文件的位置,命令如下。

复制small.cnf、my-medium.cnf、my-huge.cnf、my-innodb-heavy-4G.cnf中的一个到/etc目录下,将其命名为my.cnf,命令如下。

修改my.cnf,命令如下。

在[client]下添加如下内容。

在[mysqld]下添加如下内容

重新启动MySQL,命令如下。

查看字符集设置,命令如下。

下面介绍其他设置方法。
修改数据库的字符集,命令如下。

创建数据库,指定数据库的字符集,命令如下。

通过配置文件,修改/var/lib/mysql/mydb/db.opt。将

修改为

重新启动MySQL,命令如下。

通过MySQL命令行修改字符集,命令如下。

1.4.2 字符集乱码转换
1.数据库表字段值为乱码
笔者在处理数据库中的数据时发现了一个问题:将导出的MySQL数据库文件再次导入MySQL数据库,会出现乱码,根本无法查看其内容。究其原因,可能是在导出数据库时选择了 latin1 或其他编码类型,如图1-29所示。虽然可以查看密码,但user_name等字段显示为乱码。通过研究发现,修改字符设置等操作可以将乱码还原。
2.导出表结构
执行“mysqldump-uroot-ppassword--default-character-set=utf8-d cdb>db.sql”命令,将cdb数据库以UTF-8字符编码方式导出到db.sql文件中,如图1-30所示。
3.修改表结构的编码方式
使用记事本等编辑器对 db.sql 内的字符集设置进行修改,将“ENGINE=MyISAM DEFAULT CHARSET=latin1;”修改为“ENGINE=MyISAM DEFAULT CHARSET=utf8;”,如图1-31所示。

图1-29 某些字段显示为乱码

图1-30 导出表结构

图1-31 修改表结构的编码方式
4.将数据导出
执行“mysqldump.exe-uroot-p--quick--no-create-info--extended-insert--default-character-set=latin1 databasename>data.sql”命令,将数据库中的数据导出到本地文件中,如图1-32所示。

图1-32 将数据导出
5.修改数据库的编码方式
打开导出的data.sql文件,修改其编码方式,将“set names latin1;”改为“set names utf8;”,让客户端和链接使用UTF-8编码,将数据以UTF-8的形式存储,如图1-33所示。

图1-33 修改数据库的编码方式
6.创建数据库并将数据库表结构和数据重新导入数据库
分别执行以下命令,在数据库中创建cdb3数据库,设置默认字符编码为UTF-8,然后将数据库表结构和数据导入cdb3,如图1-34和图1-35所示。


图1-34 创建表

图1-35 重新导入表结构和数据
7.成功转码
使用Navicat for MySQL工具软件连接MySQL数据库,打开cdb3数据库中的admin_users1表。如图1-36所示,成功解决了乱码问题,user_name等字段中的中文字符已显示出来。

图1-36 成功解决乱码问题