当前位置:首页 > 问答 > 正文

数据库读取数据乱码咋整,输出显示总是不对劲怎么办

(信息来源:常见数据库操作问题汇总及开发者社区经验分享)

遇到数据库读出来的文字变成乱码,屏幕上显示一堆问号或者奇怪符号,这种情况确实让人头疼,别急着怀疑人生,这问题就像煮饺子破皮一样常见,咱们一步步来排查。

你得先搞清楚“乱码”发生在哪个环节,是整个系统所有从数据库出来的内容都乱,还是只有部分内容乱?是只有中文乱,还是其他语言也乱?这一步判断很重要,能帮你缩小包围圈,如果仅仅是新添加的中文数据乱码,而老数据正常,那问题可能出在数据“写入”的环节,而不是“读取”环节,我们今天主要聊读取显示不对的情况,但心里得有这根弦。

数据库读取数据乱码咋整,输出显示总是不对劲怎么办

第一招,检查数据库的“方言”设置(字符集编码)。 你可以把数据库想象成一个巨大的仓库,字符集就是仓库管理货品时用的“记账本”,如果仓库用的是“GBK”这本记账本,而你用卡车往外拉货(读取数据)时,却以为仓库用的是“UTF-8”记账本,那对照着错误的账本清点货物,货品的名字肯定就对不上号了,显示出来就是乱码。(参考:《MySQL必知必会》中关于字符集的比喻)

对于最常见的MySQL数据库,你可以通过一些命令来查看它的“记账本”设置,登录数据库后,执行 SHOW VARIABLES LIKE 'character_set%';SHOW VARIABLES LIKE 'collation%'; 这两条命令,你要重点关注的是 character_set_client(客户端用什么编码发指令)、character_set_connection(连接层用的编码)、character_set_database(数据库默认编码)和 character_set_results(数据库返回结果用的编码),理想情况下,它们应该和你应用程序所期望的编码(比如现在最流行的UTF-8)保持一致,如果不一致,可能就是乱码的根源。

第二招,确保连接通道的“语言”统一(连接字符串指定编码)。 你的应用程序(比如一个Java程序、一个PHP脚本)就像是一个采购员,它通过一条“数据线”(连接)向数据库仓库要数据,如果采购员只会说“UTF-8”方言,而数据库仓库默认用“GBK”回应,那沟通肯定出问题,在你建立数据库连接的代码里,明确指定使用统一的编码非常关键。(来源:Stack Overflow上高赞的数据库乱码问题解答)

数据库读取数据乱码咋整,输出显示总是不对劲怎么办

在Java的JDBC连接字符串里,你可以在URL后面加上参数像 ?useUnicode=true&characterEncoding=UTF-8,在PHP的PDO连接中,可以在创建连接后执行一条 SET NAMES 'utf8' 的SQL语句,这就相当于在打电话之前先约定好:“喂,我们等下都用普通话(UTF-8)交流啊!”这样就能保证从请求到返回,整个对话过程语言一致。

第三招,看看你的“显示器”是否匹配(应用程序或终端显示环境)。 数据从数据库里读出来,一路传送到你的程序内存里,都是正确的UTF-8编码,但最后显示在网页上、命令行窗口或者桌面软件里时,却变成了乱码,这就好比一盘录制好的高清电影(数据正确),你非要用老式录像带播放机(显示环境不支持)来看,效果肯定惨不忍睹。

对于网页显示,请检查HTML页面的 <head> 部分,是否有 <meta charset="UTF-8"> 这行标签,它告诉浏览器用UTF-8来渲染页面,对于命令行终端(比如Windows的CMD、PowerShell或者Linux的Terminal),终端本身也有一个编码设置,如果终端设置为GBK,而你打印出来的是UTF-8字符串,显示就会出错,你需要将终端的编码也调整为UTF-8(现代Linux终端通常默认就是,Windows终端可能需要手动调整)。

数据库读取数据乱码咋整,输出显示总是不对劲怎么办

第四招,终极武器:抓包看“真身”(检查原始数据)。 如果以上三板斧下去问题还没解决,那就得来点更直接的,用一个纯粹的数据库管理工具(比如Navicat、DBeaver或者MySQL自带的命令行客户端),直接连接到数据库,执行查询SQL,看看在这些专业工具里,数据显示是否正常。

如果在这里显示就乱,那问题百分百出在数据库层面或连接层面,你需要回头仔细检查第一、二步,如果在这里显示完全正常,但一到你的程序里就乱,那问题就缩小到了你的程序代码范围内,可能是你的程序在获取数据后,又进行了某种错误的字符串转换,或者是在输出到页面或控制台时处理不当,这时候,就需要在你的程序代码里设置断点,一步步调试,看看数据在哪个处理环节之后“变了脸”。

额外提醒一个隐蔽的坑:文件本身编码。 如果你的SQL脚本文件或者程序源代码文件的保存编码不是UTF-8(比如是ANSI或GBK),而里面又包含中文字符,那么即使你设置了正确的连接参数,这些中文字符在被执行或编译时,可能从一开始就已经是乱码了,确保你的代码编辑器(如VSCode、Sublime Text等)将文件保存为UTF-8编码格式。

解决数据库乱码问题,核心思路就是“统一编码”,确保数据从诞生(写入)、存储(数据库)、传输(连接)、处理(程序)到最终展示(浏览器、终端)的整个生命周期里,所有环节都使用同一种“语言”(字符编码),耐心地一个环节一个环节排除,这个问题总能被搞定。