@value 乱码_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”是等价的。

二、常见字符集

 ASCII 

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

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

 GBK 

GBK即汉字内码扩展规范,K为扩展的汉语拼音中“扩”字的声母。英文全称ChineseInternal Code Specification。GBK编码标准兼容GB2312,共收录汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一库。 GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》,1980年由国家标准总局发布。基本集共收入汉字 6763个和非汉字图形字符682个,通行于中国大陆。新加坡等地也使用此编码。GBK是对GB2312-80的扩展,也就是CP936字码表 (Code Page 936)的扩展(之前CP936和GB 2312-80一模一样)。

 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位的容器。

 UTF-8 

UTF-8(8-bitUnicode 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字符集转换过程

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

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

  • 使用每个Column的CHARACTERSET设定值;

  • 如未设置Column的CharacterSET,则使用对应表的DEFAULT CHARACTER SET设定值

  • 如Column、Table均未设地Charater SET,则使用对应数据库的DEFAULT CHARACTER SET设定值

  • 如Column、Table、Database均未设地Charater SET,则使用character_set_server设定值。

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

4d6816d813c2a42a67ee0a151a5d4c99.png

四、中文乱码现象

Mysqldump导入乱码

[root@ testserv mytest]#/usr/local/mysql/bin/mysqldump testdb t_app_control  -pxxxxxx > bc_tpc.sql[root@testserv mytest]#/usr/local/mysql/bin/mysql -uroot -pxxxxxx mytest < bc_tpc.sqlmysql> selectFGame,FArea,FGroup from  t_app_controllimit 5;+--------+----------------------+-------------+| FGame  | FArea                | FGroup      |+--------+----------------------+-------------+| ð |                  | WS--MXD || ð | 1ţ2Ģ     || ð | 1ţ3   || ð | 1ţ4ƯƯ   || ð | 1ţ5С     |+--------+----------------------+-------------+

Loaddata导入乱码

mysql> load data infile'/tmp/gongzuoshi.ttt' into table chartest;mysql> select * from chartestlimit 5;+----------+----------+-------------+--------------+| game_eng | game_chs |game_center | game_chs_new |+----------+----------+-------------+--------------+| game_eng | game_chs |game_center | game_chs_new || 1000y    | ǧ   | |              || 2c       | ˫  |     |              || 8m       |     |     |              || 9yin     | |     |             |+----------+----------+-------------+--------------+5 rows in set (0.00 sec)
五、程序及MySQL字符集配置情况

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

MySQL使用的字符集情况

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

mysql> show variables like'character%';+--------------------------+----------------------------------------+| Variable_name            | Value                                  |+--------------------------+----------------------------------------+| character_set_client     | gbk                                    || character_set_connection |gbk                                    || character_set_database   | gbk                                    || character_set_filesystem |binary                                 || character_set_results    | gbk                                    || character_set_server     |gbk                                    || character_set_system     | utf8                                   || character_sets_dir       | /usr/local/mysql/share/mysql/charsets/|+--------------------------+----------------------------------------+

Mysqldump导入乱码原因 :

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

在上例中通过mysqldump –help查看

character-sets-dir                (No default value)

通过备份文件查看

 -- MySQL dump 10.13  Distrib 5.1.52, for unknown-linux-gnu(x86_64)---- Host: localhost    Database:backupcenter-- -------------------------------------------------------- Server version       5.1.52-log/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;/*!40101SET NAMES utf8 */;

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导入乱码原因

LOAD DATA [LOW_PRIORITY |CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_name[PARTITION (partition_name,...)][CHARACTER SET charset_name][{FIELDS | COLUMNS} [TERMINATEDBY 'string'] [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ][LINES [STARTING BY 'string'][TERMINATED BY 'string']] [IGNORE number {LINES | ROWS}][(col_name_or_user_var,...)][SET col_name = expr,...]

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

Theserver uses the character set indicated by the character_set_database systemvariable to interpret the information in the file. SET NAMES and the setting of character_set_client do notaffect interpretation of input. If the contents of the input file use acharacter set that differs from the default, it is usually preferable tospecify the character set of the file by using the CHARACTER SET clause.A character set of binaryspecifies “no conversion.”

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

mysql> load data infile '/tmp/gongzuoshi.ttt' intotable chartest ; CHARACTER SET gbk
六、总结

1、编译安装MySQL的时候指定DEFAULT_CHARSET=[charset] 与写入程序保持一致

2、my.cnf中字符集设置与写入程序保持一致

3、导入数据时,将导入程序与数据库的链接配置为与数据库字符集一致

4、load data需要在语句中设置字符集参数

 ce2b409f84af48ace0704a9b067d4f56.png

了解新钛云服

招聘 | 加入我们,过上飞驰人生....

新钛云服与AWS联合举办的“混合云与云治理专家研讨会”圆满结束!

新钛云服正式获批工信部ISP/IDC(含互联网资源协作)牌照

深耕专业,矗立鳌头,新钛云服获千万Pre-A轮融资

原电讯盈科中国区副总裁加入新钛云服「附专访」

新钛云服,打造最专业的Cloud MSP+,做企业业务和云之间的桥梁

新钛云服一周年,完成两轮融资,服务五十多家客户

上海某仓储物流电子商务公司混合云解决方案

新钛云服出品的部分精品技术干货

万字长文:云架构设计原则|附PDF下载

如何将业务迁移到AWS上

AWS S3六项存储类别详解,从成本到访问频率

AWS EC2的价格模型

Ceph OSD故障排除|万字经验总结

七个用于Docker和Kubernetes防护的安全工具

维人的终身成长,从清单管理开始|万字长文!

什么是云原生?

IT混合云战略:是什么、为什么,如何构建?

9da1e3602d747104b00b8834f1a470bb.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值