MySQL数据库与表编码不⼀致_页⾯编码与数据库编码不⼀致
的情况
Mysql⾃4.1以后,增加了对字符集的⽀持。笔者之前对Mysql⽐较了解,刚接触4.1时,感觉Mysql有点多此⼀举,但后来细想发现,对字符集的⽀持,虽然对开发者来说,会⿇烦⼀些,但不可否认,是⼀种进步。对字符集的⽀持,不仅更加⽀持多语⾔,⽽且,也⽅便移植。
刚开始使⽤Mysql4.1,你可能感觉有点不适,下⾯,简单阐述⼀下笔者对Mysql4.1字符集的理解,再讲述如何PHP如何适应Mysql的这种变化,希望⼤家看过这⽂章后,能够有所收获。
如果你对计算机基础知识不了解,请直接阅读“结论篇”
⼀.原理篇
Mysql的字符集⾥有两个概念,⼀个是“Character set(字符集)”,另⼀个是“Collations”。
1. Collations
Collations翻成中⽂是“校验”,在⽹页开发的过程中,这个词汇,只在Mysql⾥使⽤,主要作⽤是指导Mys
ql对字符的⽐较,⽐如,ASCII字符集⾥,Collations规定了a⼩于b,a等于a,以及a是否等于A之类的。通常,⼤家基本可以忽略Collations的存在,因为每个字符集都有⼀个默认的Collations,通常,使⽤默认的Collations就可以了。
2.字符集
与这对⽐的是,字符集是个更⼴的概念,即使是Windows下普通的⽂本⽂件,也渗及到字符集的问题。不同的字符集,规定了不同的字符的编码⽅式。⼀个 character set (字符集)是⼀组符号和编码,⽐如,ASCII字符集,包括的字符有:数字,⼤⼩写字母,分号、换⾏之类的符号,编码⽅式是⽤⼀个7bit表⽰⼀个字符(A的编码是65,b的编码是98)。ASCII只规定了英⽂字母的编码,⾮英⽂语⾔不能⽤ASCII编码表⽰,为此,不同的国家,都为⾃⼰的语⾔做了编码,⽐如,我们国家,就有GB2312编码。但每个国家之间的编码不同,也存在着⼀些跨平台的问题,为此,⼀些国际化标准组织,就制定了⼀些国际通⽤的编码,最常⽤的就是UTF8了。ASCII只对英⽂符号和英⽂字母做了编码,GB2312对英⽂符号,英⽂字母,汉字做了编码,UTF8对世界上所有的语⾔⽂字做了编码,所以,GB1212的字符包含了ASCII字符,UTF8包含了GB2312字符。由此可见,UTF8是所含最⼴字符的字符集,所以,在⼀些多语⾔的WEB系统中,⼀般⽤UTF8字符集(PHPMyAdmin使⽤UTF8编码)。
任何⽂本的存储,都渗及到字符集的概念。包括数据库,也包括普通的⽂本⽂件。
主要术语:
字符:汉字,英⽂字母,标点符号,拉丁⽂等等。
编码:将字符转换成计算机存储的格式,⽐如,A⽤65表⽰。
字符集:⼀组字符以及对应的编码⽅式。
a. Mysql的字符集
Mysql⽬前⽀持多字符集,并且,⽀持在不同的字符集之间转换(便于移植和⽀持多语⾔)。
Mysql可以设置服务器级字符集、数据库级字符集、数据表级字符集、表列的字符集,实际上,最终使⽤字符集的地⽅是存储字符的列,⽐如,你设置 table1中col1列是字符类型,col1才⽤到了字符集,如果table1表的col2列是int类型,col2不使⽤字符集的概念。
服务器级字符集、数据库级字符集、数据表级字符集都是为列的字符集做默认选项的。
Mysql⼀定有⼀个字符集,可以通过启动时加参数指定,也可以编译时指定,也可以在配置⽂件⾥指定。Mysql服务器字符集,只是做为数据库级的默认值。创建数据库时,你可以指定字符集,如果没指
定,就使⽤服务器的字符集。同理,创建表时,你可以指定表级的字符集,如果没指定,使⽤数据库的字符集做为表的字符集。创建列时,你可以指定某列的字符集,如果没指定,就使⽤表的字符集。
通常情况下,您只需设置服务器级的字符集,其它的数据库级,表级,以及列级的字符集,都继承⾃服务器级字符集。
由于UTF8是最⼴的字符集,所以,⼀般情况下,我们设置Mysql服务器级的字符集为UTF8!
b. 普通⽂本的字符集问题
任何⽂本的存储,都存在着字符集的问题,普通⽂本⽂件也不例外。
Windows2000+的系统中,打开记事本,“保存为…”对话框,就有⼀个选项,可以让你选择存储⽂本的编码⽅式。
通常情况下,⼤家都使⽤Windows2000+的系统,都使⽤默认的编码,所以,不会碰到字符集的问题。
Windows下,保存⽂本⽂件时,可以选择编码⽅式,但打开⽂本⽂件时,都是⾃动判断编码⽅式的。⽹上有⼀个⽤Windows2000+的记事本玩移动,联通的笑话,⼤家可以搜搜,就是因为Windows在打开⽂本⽂件时,编码判断错误引起的问题。
因为⾃动判断编码有时会错误,所以,有的⽂本⽂件,规定了如何识别⾃⾝所使⽤的编码。HTML⽂件就是⼀个这样的例⼦。
HTML是⽂本⽂件。存储HTML⽂件的时候,需要使⽤⼀个编码,并且,在HTML⽂件⾥,也使⽤HTML语法,指定了该⽂件所使⽤的编码(⽐如< meta http-equiv="content-type" content="text/html; charset=UTF-8">)。如果HTML⽂件没有指定编码,则浏览器⾃动识别⽂件的编码。如果HTML指定了编码,则浏览器使⽤HTML指定的编码。
通常情况下,HTML⽂件指定的charset和HTML⽂件⾃⾝的编码是⼀致的,但也有不⼀致的情况,如果不⼀致,就会导致⽹页乱码(此处乱码,只和⽂本⽂件有关,和数据库⽆关。)使⽤专门的⽹页编辑⼯具(⽐如Dreamwave),会⾃动根据⽹页中的charset值来编码⽂件。
c. php+mysql的字符集问题
PHP最终⽣成的是⽂本⽂件,但他要取数据库⾥的⽂本,或将⽂本存进数据库。
由于Mysql⽀持多字符集,默认情况下,Mysql不知道PHP发给他的是什么编码的字符,所以,Mysql要求客户端(PHP)告诉他存取的字符集是什么。
PHP通过设置character_set_client,告诉Mysql,PHP存进数据库的是什么编码⽅式。
PHP通过设置character_set_results,告诉Mysql,PHP需要取什么样编码的数据。
PHP通过设置character_set_connection,告诉Mysql,PHP查询中的⽂本,使⽤什么编码。
MYSQL使⽤设置的编码⽅式存储⽂本。
假设Mysql使⽤setserver来存储⽂本,PHP的character_set_client是setclient,PHP的 character_set_results是setresult。那
么,Mysql将PHP发来的⽂本,从setclient编码⽅式,转换成 setserver编码⽅式,再存⼊数据库,如果PHP取⽂本,Mysql将⽂本从setserver转换成setresult,再发送给PHP。
PHP⽂件(最终⽣成的HTML⽂件)本⾝有个编码,如果Mysql传过来的编码,与PHP⽂件⾃⾝的编码不同,那么,整个⽹页,必然乱码。所以,PHP⼀般将⾃⼰的编码⽅式,告诉Mysql。
要保证不乱码,就必须将三个编码统⼀:⼀是⽹页⾃⾝的编码,⼆是HTML⾥指定的编码,三是PHP告诉Mysql的编码(包括
character_set_client和character_set_results)。
第⼀和第⼆个编码,如果使⽤DW之类的编辑器写的⽹页,通常是⼀致的,但⽤记事本写的⽹页,有可能不⼀致。
第三个编码,需要⼿⼯通知Mysql。这步可以通过在PHP⾥使⽤mysql_query(“set names characterX”)来实现。
d.字符集的转换问题
如果⼩字集转换成⼤字符集,不会丢失数据,但⼤字集,转换成⼩字集,可能会丢失数据。
⽐如,UTF8⾥有的字符,GB2312不⼀定有,所以,从UTF8转换到GB2312可能会丢失⼀些字符。
但有种情况例外,先从GB2312转成UTF8,再从UTF8转成GB2312,这种情况是不会丢数据的,因为,刚开始转换的⽂本,都是
GB2312⾥的字符,所以,整个过程都是GB2312的字符在转换,不会丢失。
写网页用什么语言正因为UTF8能容纳世界上的所有字符,所以,数据库⼀般使⽤UTF8编码。这使得,任何字符都可以存进UTF8编码的数据库。
e. PHPMyAdmin乱码的问题
PHPMyAdmin⽀持多国语⾔,这就必定要求HTML页⾯使⽤UTF8编码。
HTML页⾯使⽤UTF8编码,这就必定要求PHPMyAdmin连接Mysql时,character_set_client和character_set_results使⽤UTF8编码。
当前情况下,PHP连接Mysql只能是使⽤set names(或其它⼏个语句)来通知Mysql的编码⽅式,如果没有显式的声明编码⽅式,都将使⽤latin1编码。⼀般的程序,都没有显式声明 character_set_client变量,所以,都是将gb2312⽂本,按latin1编码⽅式存在数据
库,PHPMyAdmin再⽤utf8格式读取,肯定是乱码的。
如果PHP程序按正确的编码存⼊数据库,肯定是没有问题的。所以,需要修改的不是PHPMyAdmin.(虽然有时修改PHPMyAdmin可以解决乱码问题,但这不是问题的根本)
⼆.总结篇
上⾯的讲得有点乱,总结⼀下:
1.数据库尽量使⽤utf8存储(修改/etc/myf,在[mysqld]段加上default-character-set=utf8)
(已有的数据库,先转成UTF8格式)
2.PHP程序在查询数据库之前,执⾏mysql_query(“set names xxxx”);其中xxxx是你⽹页的编码(charset=xxxx),如果⽹页中charset=utf8,则xxxx=utf8,如果⽹页中 charset=gb2312,则xxxx=gb2312,如果⽹页中的charset=ipaddr,则xxxx=ipaddr (开个玩笑,没这编码)
⼏乎所有WEB程序,都有⼀段连接数据库的公共代码,放在⼀个⽂件⾥,在这⽂件⾥,加⼊mysql_query(“set names”)就可以了。
3.PHPMyAdmin不需要做改动。
4.需要注意的是,为保证⽹页实际编码(Windows保存对话框⾥的编码)和他声明的编码(charset=?)是⼀致的,请⽤DW之类的⼯具做⽹页。
写得有点仓促,希望⼤家指正和补充。
在MySQL中,默认使⽤的是latin1,也就是ISO8859-1字符集编码。这是⼀种8位的编码,适⽤于所有西欧字符。⽽对于汉字等是不合适的。最好、最通⽤的编码格式是utf-8,这时⼀种8位的Unicode字符集。它对于8位的西欧字符集来说,⽐较节省空间,⽽⼜能够有效地表⽰汉字等字符。因此,将MySQL数据库服务器设置为utf-8格式,把所有的MySQL数据库也设置为utf-8格式,这是最佳的选择!全世界所有语⾔都可以很好的得到⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论