使用 utf8 编码的客户端如何正确显示 latin1 编码表中的汉字?

2021-05-17 12:06:12 +08:00
 dujiangbo
数据库是 latin1 编码,使用 heidisql 或 SQLyog 客户端访问,连接数据库后发现客户端、连接、结果都是 utf8 编码,查询结果的汉字乱码。
修改 client 、connection 、results 编码为 latin1,查询结果中的汉字仍然乱码。latin1 保存的是 gbk 编码的汉字,而客户端是 utf8 编码,编码不一致导致乱码,尝试修改客户端使用 GBK 编码,没找到相关设置,请问有其他的解决方案吗?谢谢。
2237 次点击
所在节点    MySQL
13 条回复
zoharSoul
2021-05-17 12:13:03 +08:00
数据导出来, 重新建库, 重刷一遍
ch2
2021-05-17 12:18:18 +08:00
用 python 写个脚本,重新转一下字符集

```python
# -*- coding: utf-8 -*-
from __future__ import print_function
import pymysql

db_host="127.0.0.1"
user="root"
password='123456'
db="db"
mysql_connection=pymysql.connect(host=db_host, user=user, password=password, db=db,charset='utf8mb4')
number=100000

def convert():
cursor = pymysql.cursors.SSCursor(mysql_connection)
cursor.execute("select * from table")
count = 0
total = []
while True:
row = cursor.fetchone()
if not row:
break
item = {
"content": row[0].decode("gbk").encode("utf-8")
}
total.append(item)
if len(total) >= number:
hotcomment_collection.insert_many(total)
total = []
count += number
print(count)
if len(total) > 0:
#插入新的表

def main():
convert()

if __name__ == '__main__':
main()
```
dujiangbo
2021-05-17 12:29:17 +08:00
@zoharSoul 转码数据量太大,而且是线上的 WEB 在用的库,不敢动。
dujiangbo
2021-05-17 12:32:45 +08:00
@ch2 有其他不转码的方案吗?
有一个简陋的客户端用的是 GBK 编码,查询、插入中文均正常。
现在的思路是修改 heidisql 等客户端使用 gbk 编码显示,可是我找不到设置,难道没有这个功能?或者没有 GUI,需要动客户端的配置文件?
no1xsyzy
2021-05-17 13:18:09 +08:00
不能全场转码就变成所有地方动态转码

顺便,这是匈牙利命名法的正确使用范畴之一
gbkUserName = gbkFromU8(u8UserName)
你可以看到,gbk 和 gbk 位置对应,u8 和 U8 位置对应,后期 Review 很方便。
l4ever
2021-05-17 13:21:40 +08:00
xxx.encode('latin1').decode('gb2312')
ch2
2021-05-17 13:57:05 +08:00
@dujiangbo 数据量大没问题啊,你只是建个新的表而已,原有的不需要动
shmilwdc
2021-05-17 15:48:33 +08:00
@dujiangbo 可以试下 GitHub 开源的在线改表工具 gh-ost
ragnaroks
2021-05-17 16:05:26 +08:00
建了个测试库,用 heidisql 链接后,将 session charset 改为 latin1 后中文正常显示


链接字符串应该可以指定会话编码的,jdbc:// 和 ODBC 都可以
qwerthhusn
2021-05-17 16:57:17 +08:00
等一张图
dujiangbo
2021-05-19 11:33:24 +08:00
@ragnaroks 设置 set names ‘latin1’后,查询乱码,把 results 和 client 设置为 utf8 后乱码,设置为 gbk 时乱码。
推测:heidisql 前段显示为 utf8 编码。
疑问:我记得 latin1 会原封不动的存储数据,不进行转码操作,这点在另一个以 gbk 显示的客户端测试通过,names 设置为 latin1,正确显示汉字。不明白如果把 results 设置为 utf8 后,mysql 会如何处理 latin1 转 utf8 ? latin1 存储的实际是 gbk 编码的数据,期望转码应该是 gbk 转 utf8,但不知道 mysql 怎么把 latin1 转成 utf8 ?谢谢。
dujiangbo
2021-05-19 11:49:43 +08:00
按照错进错出的原则,mysql 客户端只能用 GBK 编码显示,然后 set names “latin1”才能正确显示,否则涉及汉字的字段只能用 mysql 内置函数转码才能正确显示。
ragnaroks
2021-05-19 12:08:27 +08:00
@dujiangbo 基于 heidisql 的话,选择“主机”,再选择“变量”,看看里面的数据,如果还不知道我在说啥,那我建议你重新建库或者读取后在代码内转码

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777394

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX