zoukankan      html  css  js  c++  java
  • 20080409 MySQL 4.1迁移到MySQL 5.0版本的中文乱码问题解决

    系统开过过程中,将数据库由MySQL 4.1转化到MySQL 5.0,在升级过程中遇到了中文乱码问题。先描述一下两边的服务器版本和环境。
    原:Linux,mysql-standard-4.1.8-pc-linux-i686
    新:Windows Server 2003,MySQL 5.0.45-community
    本机客户端有两个:
    MySQL AB\MySQL Connector/ODBC 3.51 = 3.51.22
    MySQL AB\MySQL Connector/Net 5.0.8.1 = 5.0.8.1

    原系统采用默认配置:
    character_set_server latin1
    character_set_database latin1
    character_set_system utf8
    character_set_client latin1
    character_set_connection latin1
    character_set_results latin1
    校对字符集为(latin1_swedish_ci是latin1的默认校对)
    collation_connection latin1_swedish_ci
    collation_database latin1_swedish_ci
    collation_server latin1_swedish_ci

    character_set_system 元数据字符集

    方案一:采用SQLyog等客户端连接MySQL4.1后dump出SQL,再Restore到MySQL 5.0。在执行过程中,发现dump出的SQL中中文数据为乱码。
    后发现直接在客户端查询MySQL 4.1中文数据也是乱码,检查发现SQLyog连接后默认会执行SET NAMES 'utf8';导致取出的数据不能正常显示。尝试SET NAMES 'latin1',取出数据还是不能正常显示,但用客户端的导出数据功能时,发现已经是正常的中文,可客户端dump查询结果依旧无法显示中文。

    方案二:ssh2上Linux服务器,用命令dump出转化后的utf8数据:
    mysqldump  --default-character-set=latin1 --character-sets-dir=utf8 -umysql -h10.1.47.6 -p ConfigV2Full > new080101.sql
    将new080101.sql传到本地打开,发现已经是中文,遂将sql导入MySQL 5.0服务器,发现依旧乱码。但利用旧的连接器连接MySQL 5.0发现中文正常,字符集依旧是latin1。

    方案三:在方案二的基础上,将new080101.sql另存为有Bom的utf8格式(用UltraEdit处理大文件有优势),再次导入,中文正常。此时字符集为utf8。

    过程可谓相当曲折。依旧对MySQL4.1用latin1字符集存中文感到疑惑。于是又去阅读了MySQL 4.1的字符集处理一节,现作一个总结。

    总结:

    MySQL的使用者大量来自拉丁国家,可能这种字符集导致的乱码问题官方不够重视,也很测试到,简单搜索就会发现MySQL中文乱码问题频频产生。

    但这不是MySQL设计者的初衷,MySQL 4.1字符集的设置是非常灵活的,其对于字符集的指定可以细化到一台机器、其中的一个数据库、其中的一张表、其中的一个字段,但是,普通开发者在创建数据库和数据表时,并没有进行那么复杂的配置,而一般使用默认配置。

    默认的配置源头来自哪里呢?来自编译。

    编译时,通常是Linux默认字符集latin1;
    安装时,在配置文件中有一个默认字符集,如果不指定,则这个值继承自编译时;
    启动时,可用命令行参数指定默认字符集,如果不指定,则这个值继承自配置文件;
    此时character_set_server被设为这个默认字符集;
    创建数据库时,如果不指定,则这个数据库的字符集被设为character_set_server;
    选定数据库时,character_set_database被设定为这个数据库字符集;
    创建一张表时,表的默认字符集被设为character_set_database
    创建一个字段时,如果不指定,则设为表的默认字符集;
    这个字符集才数据库中实际存储数据采用的字符集。就是说,如果保持默认,则所有的数据库的所有表的所有字段的都用latin1存储!

    当客户端与MySQL建立连接后,发送给MySQL的数据采用的是什么字符集?
    MySQL 无从得知 (它最多只能猜测),所以 MySQL 4.1 要求客户端必须指定这个字符集,也就是 character_set_client,MySQL 的怪异之处在于,得到的这个字符集并不立即转换为存储在数据库中的那个字符集,而是先转换为 character_set_connection 变量指定的一个字符集;转换为 character_set_connection 的这个字符集之后,还要转换为数据库默认的字符集,也就是说要经过两次转换;当这个数据被输出时,又要由数据库默认的字符集转换为 character_set_results 指定的字符集。

    但服务器上的配置中character_set_client、character_set_connection、character_set_results都是latin1,所以说还是不明白它是如何保存中文的。我估计最大的可能是,它本身把中文当作latin1存入,客户端和连接器负责了把取出的latin1转为可正常显示的中文。

    最后不得不说,MySQL将字符集细分的行为给非latin1语系开发者使用带来很大麻烦,MySQL将默认字符集设置为latin1也不够大气也不够智慧。开源是全球的,经济是全球的,世界是平的,以后的软件均使用utf8编码才是化繁就简的王道。


    附录:很烦很复杂的MySQL字符集

    character_set_server 服务器使用字符集
    character_set_database 数据库使用字符集
    character_set_system 系统内部元数据使用字符集,默认是utf8
    character_set_client 客户端指定字符集
    character_set_connection 连接时使用的字符集
    character_set_results 返回结果的字符集
    校对字符集的latin1_swedish_ci是latin1的默认值
    collation_connection latin1_swedish_ci
    collation_database latin1_swedish_ci
    collation_server latin1_swedish_ci

     

  • 相关阅读:
    P5283 [十二省联考2019]异或粽子 可持久化字典树
    P3293 [SCOI2016]美味 最大异或值 主席树
    P4735 最大异或和 可持久化trie树
    P4551 最长异或路径 trie树
    html/css静态网页制作
    在一个div里,列表样式图片进行float,实现水平排序
    css的网页布局用position
    您右下角有份、、、
    登录注册页面和页面跳转
    相对路径 绝对路径
  • 原文地址:https://www.cnblogs.com/likun/p/1144570.html
Copyright © 2011-2022 走看看