【MySQL】MySQL乱码全面解析

  说到乱码,这个应该是所有开发人员都会遇到的一个问题。在数据库中的乱码,在web页面的乱码,四处可见的乱码。在这里想好好解释一下MySQL中的乱码。

  乱码原因大家都会了解,就是编解码的不一致导致的。但是到底如何编码才能最后给用户的数据是正常可阅读的,注意这里说的是给用户的数据是正常的,即用户可以看到能识别的数据。数据库中存储的是否乱码或者程序内的是否乱码对用户是不可见的,用户也不会关心。很多时候人都会问插入数据库之后,中文乱码怎么办。其实只要处理得当,通过程序合适的编解码也可以返回正常的数据,不解决也没事;而且一定程度上还可以保证安全性,因为得到数据库内容也是无法识别具体内容,当然这不是一个正常的方式,而且很容易破解出来。话说回来,数据库存储的内容还是可以直接阅读比较好,这样通过客户端去查询的时候也会比较容易直观看到具体内容是什么;而且每次在程序中都需要编解码无论是在开发上,还是在程序运行效率上都有比较大的缺陷。

  下面我们就开始对乱码展开细致的讨论。在讲解之前我们先了解一下编解码到底是怎么回事。

编解码

  字符编解码即把字符集中的字符通过规范编码为指定字符集中的一个对象,使字符集可以进行有效存储和通过网络进行传输。很多时候,其实字符编码、字符集和代码页等概念其实指的都是同一个概念,它们都定义了有那些字符和如何把这些字符编码成为一个计算机和网络可以识别的码元。但是在有些时候两个都不是同一个概念,比如在Unicode规范中。它就分为字符表,字符集、字符编码表等概念。像我们平时说的utf8或者utf16则是字符编码表这一层的具体实现。在提到Unicode的时候就不得不说统一字符集(UCS) ISO 10646
  Unicode是由Unicode组织主要负责,该组织允许个人和各大公司加入来开发编码技术,意在解决当前编码方案的局限性。不同于Unicode,统一字符集是由ISO标准化组织来负责的。但是两个又有很大的联系,因为在开始两者没有意识到彼此的存在,等到两个组织各自技术发展中,彼此发现了对方。所以,后来两者在技术开发中慢慢趋于归一化。 从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出U+10FFFF的UCS-4编码赋值,以使得两者保持一致。所以,在某些时候,可以认为两者是统一的。
  通过上述介绍看出一个字符存储到计算机中是如下所示:字符->查询字符集->获得字符对应的编码->指定大端或者小端序->转化为二进制存储。
  相应的解码则是相反的顺序进行,读取二进制数据->根据编码规则按照大端或者小端解析数据->查找字符集->返回有效字符。

Unicode介绍

  Unicode在上面简单介绍了一下,它是一个公益性组织,主要是通过开发有效的编码规则解决当前编码结束的局限性。Unicode把字符编码划分了五个部分,主要有抽象字符集(即我们常用的字符),编码字符表(定义字符集和数值的对应关系),字符编码表(定义代表字符数值到码元对应关系),字符编码方案(对码元到字节的映射)与字符传输。通过对Unicode的介绍可以看出,整个技术只是规则的指定,具体实现则是没有做任何的限定。
  在这里着重介绍一下字符编码方案。第四部分就是字符编码方案规定了一个码元映射到字节。但是Unicode是只定义了映射规则, 具体实现没有做任何限定。比如某个字符X其码元最后映射为15位(100111100100111),如何把这两个字节的数据存储到计算机,在读取的时候如何知道这两个字节才是一个字符,而部读取三个字节或者仅读取一个字节那。这就牵涉到第四步具体的技术实现,我们常使用到的UTF-8、UTF-16等就是这一步的具体实现。这这里也可以看书UTF-8、16与32与Unicode的具体关系。 这三个仅仅是Unicode的一种技术实现。
  UTF-8与UTF-16的区别主要是码元的不同。码元指的是已编码的文本中具有最短的比特组合的单元。请注意这里是指的最短,比如一个字符编码后的字符值是257,那么其码元就是2个字节;如果是17,那码元值就是1个字节。UTF-8的码元就是1个字节,可以使用1-4个字节进行字符的编码,而UTF-16则是两个字节为一个码元,所以它的字符编码只有是2个字节或者4个字节进行字符的编码,不会出现3个字节编码的字符。

MySQL架构介绍

  介绍了字符编码相关的内容,那下面就是主要来介绍MySQL的架构,用以讲解MySQL中存在编解码的场景才能了解到哪里有可能导致数据最后的乱码。MySQL的架构是采用了数据库管理和数据管理相分离的架构设计。数据库管理主要负责的是接受客户端请求,对客户端的请求进行解析,优化和分发,调用存储引擎对数据进行操作,这里的存储引擎就是负责数据的管理;数据管理主要是对存储的数据进行最终的CRUD的操作,维护事务的实现。MySQL的架构是典型的MySQL架构图就是如下:
可以很明显的看出,对于MySQL数据库分为四层,连接器,连接池,逻辑处理,与存储引擎。在四层次的机构中,有的存在编解码,有的不存在字符的编解码,有的可能还存在多个步骤的字符编解码。上面是从大的方面进行了架构的分解,但是本篇文章主要是讲解数据库的编解码技术,所以上面的架构就略显粗糙。下面根据本篇文章的需求,我们重新绘制了数据库最红的架构体现:
  下面就针对每层进行介绍,讲解具体的编解码过程。

字符编码:http://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81

字符编码详解:http://www.crifan.com/files/doc/docbook/char_encoding/release/html/char_encoding.html#unicode_storage_and_exchange

http://blog.csdn.net/zwan0518/article/details/8928822

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值