仓酷云

标题: MYSQL网页编程之MySQL数据库中数据库移植中的乱码成绩 [打印本页]

作者: 冷月葬花魂    时间: 2015-1-16 22:19
标题: MYSQL网页编程之MySQL数据库中数据库移植中的乱码成绩
客户还是可以使用DBaaS系统所能提供的所有能力。数据库云服务消除了组织对专职人员、本地数据库存储设备的需要。他们不必安装、配置和维护任何软硬件。MySQL移植含有中文的数据时,很简单呈现乱码成绩。良多是在从MySQL4.x向MySQL5.x移植的时分呈现。MySQL的缺省字符集是latin1,在利用MySQL4.x的时分,良多人都是用的latin1字符集。而当利用MySQL5时常常乐意利用UTF-8。那末我们的义务是否是要把数据中的字符从latin1转为UTF-8呢?不是的。
用一句不年夜正确,但又对照抽象的说法是,在之前的体系中,我们是用latin1保留了利用GB系列字符集(GBK、GB2312等)的汉字。怎样如许说呢?
以下为援用的内容:
mysql>showcreatetabletestG
***************************1.row
Table:test
CreateTable:CREATETABLE`test`(
`a`varchar(100)defaultNULL
)ENGINE=InnoDBDEFAULTCHARSET=utf8
1rowinset(0.00sec)
mysql>showcreatetabletestlatin1G
***************************1.row*
Table:testlatin1
CreateTable:CREATETABLE`testlatin1`(
`a`varchar(100)defaultNULL
)ENGINE=InnoDBDEFAULTCHARSET=latin1
1rowinset(0.01sec)


字符集是告知我们,假如没有出格指定列的字符集,那末字符范例列的字符集与表的缺省字符集一样。
列的字符集是要告知MySQL,这内里保留的字符所利用的字符集是甚么。但究竟保留的是甚么字符集的字符,不由MySQL决意,MySQL也不举行反省。
在UTF-8普遍利用之前,我们利用的汉字都是GB系列的字符集,好比GB2312、GBK、GB18030等等。
在缺省字符集为latin1的MySQL中,我们一般就把GB字符集的汉字保留到数据库中,可是却告知MySQL那是latin1字符集。而GB字符集是一个汉字占两个字节,latin1是一个字符占一个字节。也就是说一个GB汉字被当做两个latin1字符来保留了。这让我想起了现在的iso8859_1,也是相似的情形。只需我们保留和读取时都看成latin1,不举行转换,然后在显现时看成GB字符集,就可以够准确利用。
那末怎样把latin1保留的汉字准确地导UTF-8字符集的数据库中呢?
起首,新的数据库中的列,要利用UTF-8字符集。一种举措是创立database时指定缺省字符集,如许在建表时假如不指定字符集则利用database的缺省字符集。
导出的数据要以latin1字符集导出,实践上就是告知MySQL导出时不做转换(由于原本的表都是latin1字符集的)。
mysqldump出来今后,再用MySQL举行导进时,还要告知MySQL,以后的数据是gb系列的字符集,好比gbk。如许,MySQL卖力把数据由gbk转换为UTF-8,保留到数据库中。
怎样告知MySQL导进的SQL是甚么字符集呢,一种办法是用--default-character-set,但偶然会起不到实践感化。这是由于mysqldump出来的文件里有setnames语句。好比:
以下为援用的内容:
headEA192.060913.sql
--MySQLdump10.10
--
--Host:localhostDatabase:EA192
------------------------------------
--Serverversion5.0.16-standard-log
/*!40101SET@OLD_CHARACTER_SET_CLIENT
=@@CHARACTER_SET_CLIENT*/;
/*!40101SET@OLD_CHARACTER_SET_RESULTS
=@@CHARACTER_SET_RESULTS*/;
/*!40101SET@OLD_COLLATION_CONNECTION
=@@COLLATION_CONNECTION*/;
/*!40101SETNAMESlatin1*/;


/*!*/是MySQL特有有句法,在其他数据库会被当做正文疏忽失落。/*!前面的40101是暗示版本,在4.1.1及以上版才实行该条语句。
这里看到有一条SETNAMESlatin1。它的一个感化是告知mysql,客户端传已往的数据是latin1字符集。由于有如许一条SETNAMES,--default-character-set也就起不到感化了。假如不幸有如许一条SQL,那末必要把它往失落大概改成SETNAMESgbk。修正大概删除的举措,当数据量对照年夜的时分,能够用head和tail来共同。好比仍是下面的谁人文件:
先用head看一下SETNAMES在第几行(数一下),下面看到是第10行。
以下为援用的内容:
wc-lEA192.060913.sql
1987EA192.060913.sql
失掉总行数是1987
head-9EA192.060913.sql>final.sql
brum@brum-laptop:~$tail-1977EA192.060913.sql
>>final.sql
brum@brum-laptop:~$

head-9是取前9行,tail-1977是取后1977行,如许就把第10行隔已往了。
失掉final.sql再用MySQL运转时,就能够利用--default-character-set=gbk了。
另有一种举措是mysqldump时利用--set-charset=false,如许就不会呈现SETNAMES了。
今朝为止,还大概有成绩,出在createtable的SQL中,好比:
以下为援用的内容:
DROPTABLEIFEXISTS`test`;
CREATETABLE`test`(
`a`varchar(100)defaultNULL
)ENGINE=InnoDBDEFAULTCHARSET=latin1;
这里仍旧有个CHARSET=latin1,它将招致新创立的表的缺省字符集是latin1,而不是我们想要的UTF8。
怎样办呢,假如数据量不年夜的话,能够思索用编纂器把它往失落大概改成UTF8,假如数据量年夜的话能够思索用sed,但大概仍旧工夫对照长。
另有一种举措就是mysqldump,利用--create-options=false,不导出表的创立属性。但假如导出的表的存储引擎分歧的话就有成绩了,由于引擎范例(innodb、myisam等)都被疏忽了。
别的,mysqldump导出时,不要利用-B,而是间接指定一个database名字,目标是不呈现CREATEDATABASE语句,由于个中也大概会出缺省字符集的子句,会影响那些未在CREATETABLE中指定字符集的表。假如你导出的SQL中有CREATEDATABASE,那末必要注重一下有无字符集的子句,假如有的话,也必要修正。
好了,经由过程上述办法导出大概处置过的导出文件可使用mysql--default-character-set=gbk来导进了。

”由于MySQL已经是一个运行了众多知名Web2.0网站的数据,包括Craigslist、Digg、Wikipedia和Google等,或许我们可以说每一个Web2.0公司实质上是一个使用MySQL数据库的公司。
作者: 变相怪杰    时间: 2015-1-19 08:36
两个月啃那本sqlserver2005技术内部-存储引擎,花了几个月啃四本书
作者: 蒙在股里    时间: 2015-1-25 11:46
备份方面可能还是一个老大难的问题。不能单独备份几个表总是感觉不爽。灵活备份的问题不知道什么时候才能解决。
作者: 山那边是海    时间: 2015-2-2 22:01
所以你总能得到相应的升级版本,来满足你的需求。
作者: 透明    时间: 2015-2-8 09:00
相信各位对数据库和怎么样学习数据库都有一些经验和看法,也会有人走了一些弯路总结出自己的经验来,希望大家能把各自的看法和经验拿出来分享,给别人一份帮助,给自己一份快乐
作者: 老尸    时间: 2015-2-25 07:46
同样会为索引视图等应用带来麻烦。看看行级和事务级的快照数据放在tempdb中,就能感觉到目前架构的尴尬。
作者: 不帅    时间: 2015-3-7 18:19
呵呵,这就是偶想说的
作者: 只想知道    时间: 2015-3-15 11:24
只能告诉你,学好数据库语言和原理,多见识几种数据库软件,比一棵树上吊死要好。
作者: 飘飘悠悠    时间: 2015-3-22 00:29
varchar(max)\\\\nvarchar(max)类型的引入大大的提高了编程的效率,可以使用字符串函数对CLOB类型进行操作,这是一个亮点。




欢迎光临 仓酷云 (http://ckuyun.com/) Powered by Discuz! X3.2