![网络攻防实战研究: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=1739349670-jGN2xNKMOssFZQB0KwS1LXjBPDtlk8v7-0-bd6898452f69ba3bf502136c4fb3a71f)
3.修改默认字符集
修改默认字符集,最简单的方法就是修改MySQL的my.ini文件中的字符集键值,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_2.jpg?sign=1739349670-jBSUNK4chLNwCZuD3IKbq8616nAMZ5gJ-0-d6e9cf05a2fcd07b9733d7fae4655f52)
修改后,重启MySQL服务,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_3.jpg?sign=1739349670-4BaeRgWEket5amD4avAcbXFDYsgMAR7W-0-102c5d6cf86949a4d9bf62123ecbf3a6)
执行“mysql>SHOW VARIABLES LIKE'character%';”命令,发现数据库编码已经是UTF-8了。
还有一种修改字符集的方法,就是使用执行MySQL命令,示例如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_4.jpg?sign=1739349670-jwxaCQEnbtR1n3FmyLxbkfBmyTv6cRLE-0-628794135ae2904f7b2299948f5d73bc)
4.在Linux中修改和查看MySQL数据库的字符集
查找MySQL的cnf文件的位置,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_5.jpg?sign=1739349670-eldFOhsQHPD64Czqy2srRuOXideewELv-0-ecec594a5f887ae6b744607b8ecfe9e9)
复制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=1739349670-TDeaBHsKzMjDU39T7gZz6e3xcvLVfPhH-0-56ddca118db3ed79ba45aa7c356460d0)
修改my.cnf,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_7.jpg?sign=1739349670-YiXYyQ2bZypYERX9r0J3FA0Kvmc5oiGr-0-45e7c97eb745eb5568fcc6849566b265)
在[client]下添加如下内容。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_8.jpg?sign=1739349670-nMznGYkoNQeRUh0aITAICMEPc2MjQVa5-0-292fbb4983615f17a96890ea74c34355)
在[mysqld]下添加如下内容
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_9.jpg?sign=1739349670-yNn87FqipYUx8goP3ksBHxpgkZkL0MmM-0-d1e25ad6b52722efb76388b763900d56)
重新启动MySQL,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_10.jpg?sign=1739349670-QRvUIie2qPTP5OhxDzWfb3S12co8oVM7-0-5f33933ad79dc00451e9148352e08230)
查看字符集设置,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_39_11.jpg?sign=1739349670-otFUBCCgEgg3xm3IsqgG56SPZnDUST4M-0-fa89b5187977e6ce537726ee139a166a)
下面介绍其他设置方法。
修改数据库的字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_1.jpg?sign=1739349670-KlN4008SITcRfVUMVPIfUUlTAss5GlOD-0-9229b10251f1331c82652f22c1561963)
创建数据库,指定数据库的字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_2.jpg?sign=1739349670-yaheVodIN1MrMDaKyGA6IyMwssMD1xIh-0-004c08fd0bf171685f793d4394b37a5c)
通过配置文件,修改/var/lib/mysql/mydb/db.opt。将
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_3.jpg?sign=1739349670-3KyRvbiee5zpvtYEpuTnmMrmhpQV32Vv-0-19d9fb1037a1fb7dc51488a44449b9fa)
修改为
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_4.jpg?sign=1739349670-jrGmHmR7g6sh1T2iM6zoqg0hMy1Ez2es-0-388c63b8a13f7ad944148d9802efc998)
重新启动MySQL,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_5.jpg?sign=1739349670-AXdLNB7ZOPquC1UPyNQQ3odai3PldtGT-0-e17977f2f56ea057c95cd09fc2ff5456)
通过MySQL命令行修改字符集,命令如下。
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_40_6.jpg?sign=1739349670-WAgAQK8IaRtVk5ipLizSmx5j7b7dJZik-0-6b1fa0e70d1fd5059b8f7c07427a0afe)
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=1739349670-dwQWtdcYzsRA3wf5Y8vXElCbBnhW47ZD-0-b74e329a25b47e30695e4e0bcfa513ae)
图1-29 某些字段显示为乱码
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_2.jpg?sign=1739349670-Ht0ylyj2VIE7uoUca3SlRlMS8DiDTI4r-0-19513d102f58e2e779006f3109c51029)
图1-30 导出表结构
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_41_3.jpg?sign=1739349670-EwShdDpBJ1d2CUGmR1CkHjULF5LQUpae-0-841539bffea4318a1ee3c5bb584efec6)
图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=1739349670-TxEQ5aCHV4i4fcjfakUM00K6zu5ia12n-0-6d8f07ad26363eca527fd5fb9347eb71)
图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=1739349670-8kPxCBDYCMPutNglXs5NpBN39cp9hkAM-0-f4baa75543f74c4281365b4d39980ce4)
图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=1739349670-dlLCaB4gULT68Ger4le6FDDoKyzgXUZC-0-571e04c3613abec7b4f44b7ca281c03a)
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_3.jpg?sign=1739349670-b8WlQpDhlRtVwEQdwBT3mfoRR3lAn9EW-0-119ea77d842342e442d3e7a4bda36f65)
图1-34 创建表
![](https://epubservercos.yuewen.com/E55E1D/18279401208274706/epubprivate/OEBPS/Images/35530_42_4.jpg?sign=1739349670-h2lETLHow1bJXy3uAmKX57hVbGQMRTsw-0-92eef8f39c6b5f374ba45d4189b09abb)
图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=1739349670-I1Ft5cL2I2FNrjr0xHK265jLrdVXQtdi-0-5da520dfb6caa5e8c7919697ffd73697)
图1-36 成功解决乱码问题