V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
dujiangbo
V2EX  ›  MySQL

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

  •  
  •   dujiangbo · 2021-05-17 12:06:12 +08:00 via iPhone · 2241 次点击
    这是一个创建于 1285 天前的主题,其中的信息可能已经有所发展或是发生改变。
    数据库是 latin1 编码,使用 heidisql 或 SQLyog 客户端访问,连接数据库后发现客户端、连接、结果都是 utf8 编码,查询结果的汉字乱码。
    修改 client 、connection 、results 编码为 latin1,查询结果中的汉字仍然乱码。latin1 保存的是 gbk 编码的汉字,而客户端是 utf8 编码,编码不一致导致乱码,尝试修改客户端使用 GBK 编码,没找到相关设置,请问有其他的解决方案吗?谢谢。
    13 条回复    2021-05-19 12:08:27 +08:00
    zoharSoul
        1
    zoharSoul  
       2021-05-17 12:13:03 +08:00
    数据导出来, 重新建库, 重刷一遍
    ch2
        2
    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
        3
    dujiangbo  
    OP
       2021-05-17 12:29:17 +08:00 via iPhone
    @zoharSoul 转码数据量太大,而且是线上的 WEB 在用的库,不敢动。
    dujiangbo
        4
    dujiangbo  
    OP
       2021-05-17 12:32:45 +08:00 via iPhone
    @ch2 有其他不转码的方案吗?
    有一个简陋的客户端用的是 GBK 编码,查询、插入中文均正常。
    现在的思路是修改 heidisql 等客户端使用 gbk 编码显示,可是我找不到设置,难道没有这个功能?或者没有 GUI,需要动客户端的配置文件?
    no1xsyzy
        5
    no1xsyzy  
       2021-05-17 13:18:09 +08:00
    不能全场转码就变成所有地方动态转码

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


    链接字符串应该可以指定会话编码的,jdbc:// 和 ODBC 都可以
    qwerthhusn
        10
    qwerthhusn  
       2021-05-17 16:57:17 +08:00
    等一张图
    dujiangbo
        11
    dujiangbo  
    OP
       2021-05-19 11:33:24 +08:00 via iPhone
    @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
        12
    dujiangbo  
    OP
       2021-05-19 11:49:43 +08:00 via iPhone
    按照错进错出的原则,mysql 客户端只能用 GBK 编码显示,然后 set names “latin1”才能正确显示,否则涉及汉字的字段只能用 mysql 内置函数转码才能正确显示。
    ragnaroks
        13
    ragnaroks  
       2021-05-19 12:08:27 +08:00
    @dujiangbo 基于 heidisql 的话,选择“主机”,再选择“变量”,看看里面的数据,如果还不知道我在说啥,那我建议你重新建库或者读取后在代码内转码
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1043 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:29 · PVG 03:29 · LAX 11:29 · JFK 14:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.