一、概述
公司新购了一批PC,准备把几个性能较优的PC升级为数据库服务器,替换老旧的机器。公司有套POS终端软件,后台数据存储是 MySQL 3.23 版。我准备硬件升级的同时升级数据库软件。但是升级过程中遇到闻名的 MySQL 的乱码问题。经过查找资料,加上自己的摸索和经验,终于完美地解决这个问题。
MySQL 的乱码问题(不仅仅包括中文乱码,也包括其它语言的乱码,以下称之为乱码问题)只存在于4.1及其以上版本。4.1之前的 MySQL 不支持多语言,所以它会将你给它的数据“原封不动地保存,再“原封不动地读出来。从字节的角度来看,数据在这一过程中不会产生任何变化,因此不会有乱码。
4.1及以后的版本开始支持多语言,这个所谓的多语言,就是在输入输出时 MySQL 会替你做编码转换。而这个转换规则就是由客户端编码和服务器端编码来决定的。
编码转换的规则就是,在输入数据时将编码由“客户端编码转换为“服务器端编码,输出时将数据由“服务器端编码转换为“客户端编码。
二、乱码产生原因
MySQL 字符编码是版本4.1引入的,支持多国语言,而且一些特性已经超过了其它大多数数据库管理系统。正因为这一特性才导致 MySQL 的乱码问题。
字符集是一套符号和编码。校对规则是在字符集内用于比较字符的一套规则。让我们使用一个假想字符集的例子来区别清楚。
假设我们有一个字母表使用了四个字母:‘A’、‘B’、‘a’、‘b’。我们为每个字母赋予一个数值:‘A’=0,‘B’= 1,‘a’= 2,‘b’= 3。字母‘A’是一个符号,数字0是‘A’的编码,这四个字母和它们的编码组合在一起是一个字符集。
假设我们希望比较两个字符串的值(在if……else语句中我们经常做值的比较):‘A’和‘B’。比较的最简单的方法是查找编码:‘A’为0,‘B’为1。因为0 小于1,我们可以说‘A’小于‘B’。我们做的仅仅是在我们的字符集上应用了一个校对规则。校对规则是一套规则(在这种情况下仅仅是一套规则):“对编码进行比较。我们称这种全部可能的规则中的最简单的校对规则为一个binary(二元)校对规则。
但是,如果我们希望小写字母和大写字母是等价的,应该怎样?那么,我们将至少有两个规则:(1)把小写字母‘a’和‘b’视为与‘A’和‘B’等价;(2)然后比较编码。我们称这是一个大小写不敏感的校对规则。比二元校对规则复杂一些。