![网络攻防实战研究:MySQL数据库安全](https://wfqqreader-1252317822.image.myqcloud.com/cover/600/34171600/b_34171600.jpg)
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.查看默认字符集
查看系统的字符集和排序方式,可以通过下面两条命令实现。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_1.jpg?sign=1739286386-KLmFdEWWcVP0zAPFMhAwlQr26ZT7Hh3Z-0-b603811fd4d9357855a2a7240af256f7)
3.修改默认字符集
修改默认字符集,最简单的方法就是修改MySQL的my.ini文件中的字符集键值,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_2.jpg?sign=1739286386-oJjeGL3zxO5cSKAEkDkLTsU5PU6yEFsT-0-201ed62c9293d1abfac9c8178726eabf)
修改后,重启MySQL服务,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_3.jpg?sign=1739286386-Cyw1cPoqP0qUdJCqhfl9tG2dIRk0UJMA-0-8f9559cea3145856a07b73276c4ed804)
执行“mysql>SHOW VARIABLES LIKE'character%';”命令,发现数据库编码已经是UTF-8了。
还有一种修改字符集的方法,就是使用执行MySQL命令,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_4.jpg?sign=1739286386-5AhY55tCtt86a2ERb6C9wdma69t4ztlU-0-3d2f14b46344d51f07b4156620a5b009)
4.在Linux中修改和查看MySQL数据库的字符集
查找MySQL的cnf文件的位置,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_5.jpg?sign=1739286386-BFQBEv7cPdTijWBfTzF4nu14FyC3P8bf-0-23279503806725556601db71c5d1fdc9)
复制small.cnf、my-medium.cnf、my-huge.cnf、my-innodb-heavy-4G.cnf中的一个到/etc目录下,将其命名为my.cnf,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_6.jpg?sign=1739286386-i1S0UmCi2iLKWeBJViZKXV8WerUgghfU-0-4f2efd47be5e9a6fc8f9c405d5a01f46)
修改my.cnf,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_7.jpg?sign=1739286386-tzN64qOFY9z8Xon7i4L4DUThoebzyvR9-0-cf7f8b95031c27ff40bf3e40bf3a9efb)
在[client]下添加如下内容。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_8.jpg?sign=1739286386-UZ8gkYNr8x4QIXgXPQe5wdsV0ThExDrp-0-3276c0b4aee5554c32ad5d3d21d93b12)
在[mysqld]下添加如下内容
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_9.jpg?sign=1739286386-EjpYGzjgeJ2ZhPJno5YAtgaJTXg1Cjs0-0-e07cfa0c1f597af652ae82a95ea8e93a)
重新启动MySQL,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_10.jpg?sign=1739286386-DHk7VvnCu6XNyTXUn8O29EGVKjLC2FD4-0-4e846ff67065b53ca210887a8a569fd5)
查看字符集设置,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_11.jpg?sign=1739286386-2lCvl4kG6yWMqvuJ1wsBDAvTcolzY1FO-0-5105ca37a9ef4cf873de241a4730b404)
下面介绍其他设置方法。
修改数据库的字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_1.jpg?sign=1739286386-0bWigwWoC1S1m4WADvYnohmDQnFXIvy3-0-2d00043b5d35bc36786180db838a9559)
创建数据库,指定数据库的字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_2.jpg?sign=1739286386-AcNWDPprvdbtQqI0eQz6DcSqTuAtFDLP-0-b7bf456dfa3fbf21a38ecff2a9aec63c)
通过配置文件,修改/var/lib/mysql/mydb/db.opt。将
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_3.jpg?sign=1739286386-OBN3bMZ3eiR7QjQItTw3VxrhJnuhgNdY-0-fade1779ca0accbbb0576e59b8654fa7)
修改为
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_4.jpg?sign=1739286386-vC11HhTURZU14VNQwMPYbSMdCyFzaQ3j-0-95e0952951d3199a647a6fa8b708f8f4)
重新启动MySQL,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_5.jpg?sign=1739286386-9kTTYUQZQCwJbR5JpiGz86j4g4pD5qDK-0-8862ef6cfdfe283489a25674cf068e9e)
通过MySQL命令行修改字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_6.jpg?sign=1739286386-ClopnP2rTtcqjWNXqMh01qhIMi1ijWr0-0-7c623fe3cc0b5ac87bc296ef9279fccb)
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所示。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_1.jpg?sign=1739286386-Fph0ipwH8kiQoTIWGtgvyQhViCgNgCWk-0-2bbc393ec4ad4b1a59f55fd8a4f57423)
图1-29 某些字段显示为乱码
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_2.jpg?sign=1739286386-HO6m5hWFYaF1MWWbPH9fr2vA8Ll64dl1-0-387fec2a5b9bbe45ba2644a12f97edda)
图1-30 导出表结构
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_3.jpg?sign=1739286386-saPwQ5uHTwCpLKpa9eeBImSYxViUKQHs-0-c43c1a07a1a96d99d0010ad0dc17c98f)
图1-31 修改表结构的编码方式
4.将数据导出
执行“mysqldump.exe-uroot-p--quick--no-create-info--extended-insert--default-character-set=latin1 databasename>data.sql”命令,将数据库中的数据导出到本地文件中,如图1-32所示。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_4.jpg?sign=1739286386-AyZaPXhv47rGNqxTMujxaujk3nhPulpr-0-5c5781027c872b342a35b190f2bbc137)
图1-32 将数据导出
5.修改数据库的编码方式
打开导出的data.sql文件,修改其编码方式,将“set names latin1;”改为“set names utf8;”,让客户端和链接使用UTF-8编码,将数据以UTF-8的形式存储,如图1-33所示。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_1.jpg?sign=1739286386-V8EqUFk7Rn5FlFda7YeHBxqxvNkwBDvw-0-569ea4c41f6fc04a4fe543f40fe0c2fe)
图1-33 修改数据库的编码方式
6.创建数据库并将数据库表结构和数据重新导入数据库
分别执行以下命令,在数据库中创建cdb3数据库,设置默认字符编码为UTF-8,然后将数据库表结构和数据导入cdb3,如图1-34和图1-35所示。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_2.jpg?sign=1739286386-CiKjxEpz9P8Nueu7W5Txm0MLS9vBcD6j-0-76c35be006bd0ca46c0aed1218353fe6)
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_3.jpg?sign=1739286386-gUbYyO33IkwlX2fUOSolulhbEUWC5cKN-0-c19d2245dafe6aa95e2e866ec6590c7c)
图1-34 创建表
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_4.jpg?sign=1739286386-6ntisgR8Mg5hnCzObJgmsIInuS7gdxXX-0-5aa5a833a42f989d4b7dc9cfe3fe13a4)
图1-35 重新导入表结构和数据
7.成功转码
使用Navicat for MySQL工具软件连接MySQL数据库,打开cdb3数据库中的admin_users1表。如图1-36所示,成功解决了乱码问题,user_name等字段中的中文字符已显示出来。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_43_1.jpg?sign=1739286386-grikQzHFVW2KEM0xNZ8ixoue8C876iQx-0-80cf422c8af7351dd83abdcbb2d46183)
图1-36 成功解决乱码问题