首页 > 数据库 >如何解决MySQL字符集乱码问题

如何解决MySQL字符集乱码问题

时间:2023-03-07 16:06:46浏览次数:48  
标签:字符 编码 字符集 乱码 导入 ISO MySQL

MySQL自4.1版本推出之后由于中文的特殊性带来的乱码问题也随在互联网行业出现。主要原因就是不同字符集编码不同而产生的。本文简要介绍字符集相关知识及部分乱码情况的解决方式。

一、字符集本概念

字符集的基本概念如下 :

字符(Character)是指人类语言中最小的表义符号。例如’A’、’B’等
给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding)。例如,我们给字 符’A’赋予数值0,给字符’B’赋予数值1,则0就是字符’A’的编码
给定一系列字符并赋予对应的编码后,所有这些字符和编码对组成的集合就是字符集(Character Set)。例如,给定字符列表为{’A’,’B’}时,{’A’=>0, ‘B’=>1}就是一个字符集
字符序(Collation)是指在同一字符集内字符之间的比较规则
确定字符序后,才能在一个字符集上定义什么是等价的字符,以及字符之间的大小关系
每个字符序唯一对应一种字符集,但一个字符集可以对应多种字符序,其中有一个是默认字符序(Default Collation)
MySQL中的字符序名称遵从命名惯例:以字符序对应的字符集名称开头;以_ci(表示大小写不敏感)、_cs(表示大小写敏感)或_bin(表示按编码值比较)结尾。例如:在字符序“utf8_general_ci”下,字符“a”和“A”是等价的。

二、常见字符集

1) ASCII

ASCII是英文American Standard Code for Information Interchange的缩写,美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语和其他西欧语言。它是现今最通用的 单字节编码系统,并等同于国际标准ISO/IEC 646。

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。

2)GBK

GBK即汉字内码扩展规范,K为扩展的汉语拼音中“扩”字的声母。英文全称Chinese Internal Code Specification。GBK编码标准兼容GB2312,共收录汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。

GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,1980年由国家标准总局发布。基本集共收入汉字 6763个和非汉字图形字符682个,通行于中国大陆。新加坡等地也使用此编码。GBK是对GB2312-80的扩展,也就是CP936字码表 (Code Page 936)的扩展(之前CP936和GB 2312-80一模一样)。

3)latin1

Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。

ISO-8859-1
ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。

ISO-8859-1收录的字符除ASCII收录的字符外,还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号出现的比较晚,没有被收录在ISO-8859-1当中。

因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个 特性。ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。

4)UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到4个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如日文,韩文)

UTF-8以字节为单位对Unicode进行编码。

UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8 编码的最大长度是4个字节。

从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。Unicod的最大码位0x10FFFF也只有21 位。

如何解决MySQL字符集乱码问题_MySQL

三、MySQL字符集转换过程

1. MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection

2. 进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:

1) 使用每个Column的CHARACTER SET设定值;
2) 如未设置Column的Character SET,则使用对应表的DEFAULT CHARACTER SET设定值
3) 如Column、Table均未设地Charater SET,则使用对应数据库的DEFAULT CHARACTER SET设定值
4) 如Column、Table、Database均未设地Charater SET,则使用character_set_server设定值。

3. 将操作结果从内部操作字符集转换为character_set_results

如何解决MySQL字符集乱码问题_MySQL_02

四、中文乱码现象

Mysqldump导入乱码

如何解决MySQL字符集乱码问题_MySQL_03

Load data导入乱码

如何解决MySQL字符集乱码问题_MySQL_04

五、程序及MySQL字符集配置情况

出现乱码情况,首先确认写入程序使用的字符集,MySQL使用的字符集
MySQL使用的字符集情况

通过SHOW VARIABLES LIKE ‘character%’,在上面例子中通过语句获得字符集设置情况如下:

如何解决MySQL字符集乱码问题_MySQL_05

Mysqldump导入乱码原因 :

1、 首先确认mysqldump –help或查看备份文件头部信息确认默认字符集
在上例中通过mysqldump –help查看

通过备份文件查看

如何解决MySQL字符集乱码问题_mysql_06

2、 通过 mysql –help 确认导入字符集

default-character-set        gbk

导入的两种情况如下

1)不修改备份文件,导入由于sql文件中存在set names utf8,则导入后字符集使用的依然是utf8,在系统默认显示字符集为gbk的情况下,则显示为乱码,此时则需要使用set names utf8 才能正常显示字符

2)修改备份文件,导入前将sql中的set names utf8 去除,在mysql默认字符集为gbk的情况下导入后字符集为gbk,此时mysql显示字符集为 gbk,两者一致,则显示正常

Load data导入乱码原因

如何解决MySQL字符集乱码问题_MySQL_07

对于load data导入乱码问题的具体解释在官方文档中有提及,请参考:

如何解决MySQL字符集乱码问题_备份文件_08

这些是无法影响到导入结果的,因此应使用Load 自身的字符集参数来进行数据导入,如下方式:

mysql>load data infile '/tmp/gongzuoshi.ttt' into chartest ; CHARACTER
SET gbk

六、总结

1、 编译安装MySQL的时候指定DEFAULT_CHARSET=[charset] 与写入程序保持一致
2、 my.cnf中字符集设置与写入程序保持一致
3、 导入数据时,将导入程序与数据库的链接配置为与数据库字符集一致
4、load data需要在语句中设置字符集参数


标签:字符,编码,字符集,乱码,导入,ISO,MySQL
From: https://blog.51cto.com/u_12148962/6103121

相关文章

  • MySQL 并行复制方案演进历史及原理分析
    预告:《MySQL实战》即将出版,敬请关注!有线上MySQL维护经验的童鞋都知道,主从延迟往往是一个让人头疼不已的问题。不仅仅是其造成的潜在问题比较严重,而且问题的定位尤其考......
  • Linux(Centos7)下rpm方式安装MySQL
    1.卸载已有MySQL1.1.查看是否已安装mysqlrpm-qa|grep-imysql如果系统已安装,请卸载删除。1.2.删除MySQL删除命令:rpm-e--nodeps包名rpm-evmysql-......
  • Ubuntu 通过 docker 启动 mysql
    1、首先拉取MySQL的镜像dockerpullmysql2、运行mysql容器dockerrun--namemysql-p3306:7080-eMYSQL_ROOT_PASSWORD=88888888mysql--namemysql......
  • MySQL查询数据库所有表名及其注释
    1、查看Mysql数据库"ori_data"下所有表的表名、表注释及其数据量SELECTTABLE_NAME表名,TABLE_COMMENT表注释,TABLE_ROWS数据量FROMinformation_schema.tablesWHERE......
  • 财务软件打开乱码问题处理方法(自然人报税扣缴、etax3.0、鼎信诺等)
    1、首先保证电脑的系统区域、输入法区域、时区都处于中国,日期格式为yyy/MM/dd格式,设置完成后重启计算机。系统区域、输入法区域和时区可以根据这篇文章的方法查询:命令查看......
  • docker mysql 忘记了密码
    title:dockermysql忘记了密码,2059-Authenticationplugin‘caching_sha2_password‘cannotbeloaded:报错的解决办法date:2023-03-07T14:18:38Zlastmod:2023-0......
  • mysql高级
    1.索引优缺点:  优:提高检索效率,降低IO成本。通过索引排序,降低cpu消费。  缺:索引需要占用空间,降低表更新效率   2.索引结构     1)B+Tree:......
  • 使用Python操作Mysql数据库(进阶)
    #-*-coding:utf-8-*-importloggingimportpymysqlfromrest_framework.responseimportResponselogger=logging.getLogger(__name__)#连接数据库def......
  • mysql执行计划:Explain语句结果中各个字段分表表示什么
    mysql执行计划:Explain语句结果中各个字段分表表示什么列名描述id查询语句中每出现⼀个SELECT关键字,MySQL就会为它分配⼀个唯⼀的id值,某些⼦查询会被优化为join......
  • 如何在windows环境下安装启动mysql实录
    1.下载mysql笔者下载的mysql-8.0.32-winx642.生成.ini配置文件在与bin目录同级下创建my.ini文件内容如下:(笔者的端口创建为3307,通常是3306,可自定义修改)[mysqld]#设置3307端......