千家信息网

mysql 字符集乱码探究

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,环境描述:青云的mysql实例的ip为:192.168.0.254,和青云的跳板主机,我们在跳板主机上安装了mysql服务,并通过下面方式连接mysql: [root@i-iivphroy ~]# m
千家信息网最后更新 2025年02月01日mysql 字符集乱码探究环境描述:青云的mysql实例的ip为:192.168.0.254,和青云的跳板主机,我们在跳板主机上安装了mysql服务,并通过下面方式连接mysql: [root@i-iivphroy ~]# mysql -uroot -p********* -h292.168.0.254 问题描述:近期网站整体迁云,需要先迁移一部分数据到云,采用mysqldump的方法,可是在云上source完成之后,却发现中文乱码。 一:查看源端mysql的相关信息。 1:查看源端mysql的表的字符集,为utf8. mysql> show create table v_publish_info; 。 。 。 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 2:查看mysql关于字符集的参数, MariaDB [log]> show variables like 'collation_%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ 3 rows in set (0.00 sec) MariaDB [log]> show variables like 'character_set_%'; +--------------------------+------------------------+ | Variable_name | Value | +--------------------------+------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /mysql/share/charsets/ | 二:查看目标云端的相关信息 1,查看目标端mysql的表的字符集,为utf8. mysql> show create table v_publish_info; 。 。 。 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 2,查看mysql关于字符集的参数,发现是latin1 mysql> show variables like 'character_set_%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | latin1 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) mysql> show variables like 'collation_%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_general_ci | | collation_server | latin1_general_ci | +----------------------+-------------------+ 3 rows in set (0.01 sec) 原来是青云的mysql默认的字符集相关参数是latin1,但是我们的表是utf8,这导致乱码,验证: 在云端修改参数,都改成utf8,也就是改成和源端一样, mysql> set character_set_client=utf8 ; mysql> set character_set_connection =utf8 ; 。 。 。 mysql> set collation_server =utf8_general_ci ; 再次查看数据,中文不再乱码: mysql> select title from v_publish_info limit 2; +-----------------------------------------------------------------------------------------------------------------+ | title | +-----------------------------------------------------------------------------------------------------------------+ | 即墨省级经济开发区蓝色新区管理委员会关于体育中心铜铝复合散热器邀请报价的函 | | 2015年招投标领域十大关键词 | +-----------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) 既然确定了就是这些参数导致的问题,那么接下来开始解决问题,前面修改的参数,仅仅是在当前会话生效的,新开session无效,于是通过控制台修改mysql的参数, character_set_server=utf8 然后重启mysql实例,然后再次查看mysql的数据,发现依旧乱码, mysql> select title from v_publish_info limit 2; +---------------------------------------+ | title | +---------------------------------------+ | ????????????????????????????????????? | | 2015??????????? | +---------------------------------------+ 2 rows in set (0.00 sec) 再次查看相关参数:发现还有 latin1 mysql> show variables like 'character_set_%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) mysql> show variables like 'collation_%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec) 我们已经把mysql服务端的相关参数修改了,剩下的是clint端的参数,我们是通过下面方式连接数据库的,也就是说mysql并没有在这台服务器上,而是在192.168.0.254上面的。 [root@i-iivphroy ~]# mysql -uroot -p********* -h292.168.0.254 突然想到那这台跳板机就相当于是客户端了,这里面也有my.cnf的配置文件,尝试去修改这里,如下红色部分,是设置客户端的参数的: [root@i-iivphroy ~]# cat /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid #[mysqld] #default-character-set=utf8 #init_connect = 'SET NAMES utf8' [client] default-character-set=utf8 然后从新登录数据库: [root@i-iivphroy ~]# mysql -uroot -p********* -h292.168.0.254 再次查看相关参数,彻底和源端一样了: mysql> show variables like 'collation_%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ 3 rows in set (0.01 sec) mysql> show variables like 'character_set_%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) 再次查看数据,不在乱码: mysql> select title from v_publish_info limit 2; +-----------------------------------------------------------------------------------------------------------------+ | title | +-----------------------------------------------------------------------------------------------------------------+ | 即墨省级经济开发区蓝色新区管理委员会关于体育中心铜铝复合散热器邀请报价的函 | | 2015年招投标领域十大关键词 | +-----------------------------------------------------------------------------------------------------------------+ 下面讲解下这几个参数 系统变量: - character_set_server:默认的内部操作字符集 - character_set_client:客户端来源数据使用的字符集 - character_set_connection:连接层字符集 - character_set_results:查询结果字符集 - character_set_database:当前选中数据库的默认字符集 - character_set_system:系统元数据(字段名等)字符集 - 还有以collation_开头的同上面对应的变量,用来描述字符序。 1.库、表、列字符集的由来: (1).建库时,若未明确指定字符集,则采用character_set_server指定的字符集。 (2).建表时,若未明确指定字符集,则采用当前库所采用的字符集。 (3).新增,修改表字段时,若未明确指定字符集,则采用当前表所采用的字符集。 2.更新、查询涉及到得字符集变量: 用户在更新(插入,删除,修改),查询数据库时,最常使用的字符集变量主要包含:character_set_client,character_set_connection,character_set_result。 (1)更新流程字符集转换过程:character_set_client------->character_set_connection----->表字符集。 (2)查询流程字符集转换过程:表字符集------->character_set_result 总结:通过这次解决问题的过程,修正了我原来的认识,原来数据库的参数,可以通过修改客户端(数据库没在这个服务器上)的配置文件my.cnf来改变,并且了解到了查询一条数据,需要把表的字符集转换成character_set_result的字符集,乱码你就修改这个character_set_result参数即可。并且mysql数据库的my.cnf最好设置上如下两个参数: [mysqld] default-character-set=utf8 [client] default-character-set=utf8
0