`

MySQL数据库中数据库移植中的乱码问题

    博客分类:
  • SQL
阅读更多
mysql> source d:\test.sql
MySQL数据库中数据库移植中的乱码问题 2009年08月17日 4:53 下午  |  分类:默认MySQL移植含有中文的数据时,很容易出现乱码问题。很多是在从MySQL4.x向MySQL5.x移植的时候出现。MySQL的缺省字符集是latin1,在使用MySQL4.x的时候,很多人都是用的latin1字符集。而当使用MySQL5时往往愿意使用UTF-8。那么我们的任务是不是要把数据中的字符从latin1转为UTF-8呢?不是的。

用一句不大准确,但又比较形象的说法是,在之前的系统中,我们是用latin1保存了使用GB系列字符集(GBK、GB2312等)的汉字。怎么这样说呢?

mysql> show create table test\G
*************************** 1. row
Table: test
Create Table: CREATE TABLE `test` (
`a` varchar(100) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> show create table testlatin1\G
*************************** 1. row *
Table: testlatin1
Create Table: CREATE TABLE `testlatin1` (
`a` varchar(100) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)

字符集是告诉我们,如果没有特别指定列的字符集,那么字符类型列的字符集与表的缺省字符集一样。

列的字符集是要告诉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出来的文件里有set names语句。比如:

head EA192.060913.sql

– MySQL dump 10.10

– Host: localhost Database: EA192
– ———————————-
– Server version 5.0.16-standard-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 */;
/*!40101 SET NAMES latin1 */;

/*! */是MySQL特有有句法,在其他数据库会被当成注释忽略掉。/*!后面的40101是表示版本,在4.1.1及以上版才执行该条语句。

这里看到有一条SET NAMES latin1。它的一个作用是告诉mysql,客户端传过去的数据是latin1字符集。因为有这样一条SET NAMES,–default-character-set也就起不到作用了。如果不幸有这样一条SQL,那么需要把它去掉或者改成SET NAMES gbk。修改或者删除的办法,当数据量比较大的时候,可以用head和tail来配合。比如还是上面的那个文件:

先用head看一下SET NAMES在第几行(数一下),上面看到是第10行。

wc -l EA192.060913.sql
1987 EA192.060913.sql
得到总行数是1987

head -9 EA192.060913.sql > final.sql
brum@brum-laptop:~$ tail -1977 EA192.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,这样就不会出现SET NAMES了。

目前为止,还可能有问题,出在create table的SQL中,比如:

DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`a` varchar(100) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

这里仍然有个CHARSET=latin1,它将导致新创建的表的缺省字符集是latin1,而不是我们想要的UTF8。

怎么办呢,如果数据量不大的话,可以考虑用编辑器把它去掉或者改成UTF8,如果数据量大的话可以考虑用sed,但可能仍然时间比较长。

还有一种办法就是mysqldump,使用–create-options=false,不导出表的创建属性。但如果导出的表的存储引擎不同的话就有问题了,因为引擎类型(innodb、myisam等)都被忽略了。

此外,mysqldump导出时,不要使用-B,而是直接指定一个database名字,目的是不出现CREATE DATABASE语句,因为其中也可能会有缺省字符集的子句,会影响那些未在CREATE TABLE中指定字符集的表。如果你导出的SQL中有CREATE DATABASE,那么需要注意一下有没有字符集的子句,如果有的话,也需要修改。

好了,通过上述方法导出或者处理过的导出文件可以使用mysql –default-character-set=gbk来导入了
分享到:
评论

相关推荐

    Mysql数据库编码问题 (修改数据库,表,字段编码为utf8)

    总之,选择UTF-8作为MySQL数据库的字符集能够确保兼容性和可移植性,同时在处理多语言数据时更加灵活。在实际操作中,务必确保所有环节(数据库、表、连接、页面编码)的一致性,以避免字符乱码问题。

    MySQL数据库字符集的问题研究.pdf

    在实际操作MySQL数据库的过程中,常见的字符集问题主要包括: 1. **数据库中的中文字符乱码显示**。 2. **Web页面显示数据库中的中文字符时出现乱码**。 3. **无法正确存储一些特殊字符,如emoji表情**。 #### 五...

    pymysql python连接mysql数据库

    在Python编程中,与MySQL数据库进行交互是常见的需求,而PyMySQL就是这样一个用于Python连接MySQL的库。PyMySQL是一个纯Python实现的MySQL客户端,它提供了与MySQL通信的接口,使得Python开发者可以方便地执行SQL...

    java插入数据乱码解决集锦

    在数据库连接字符串中加入字符集参数,例如对于MySQL数据库:`jdbc:mysql://localhost/digitgulf?user=root&password=root&useUnicode=true&characterEncoding=utf8`。 2. 在处理数据之前,通过`response....

    JAVA常见中文乱码问题解决方法

    Java编程语言在处理中文字符时可能会遇到乱码问题,这主要源于Java的源代码编码、JVM处理class文件以及不同操作系统、数据库系统之间的编码不一致。本文深入剖析了Java中文问题的根源,并提供了相应的解决方案。 一...

    网页中文乱码完美解决方案.pdf

    本文档旨在解决网页中文乱码问题,提供了三个方面的解决方案:APACHE 服务器设置、PHP 编码问题和 MYSQL 数据库的表以及字段编码。 APACHE 服务器设置 APACHE 服务器的配置文件中有一行是编码的设置,默认的是 ...

    Mysql迁移Oracle方案

    - **乱码验证**:检查Oracle数据库中是否存在乱码问题,特别是针对中文或其他非英文字符。 综上所述,MySQL到Oracle的数据迁移涉及多个步骤和技术细节,需要严格按照上述流程操作,并在每个环节仔细核对,确保数据...

    mysql导出工具.rar

    MySQL数据库是世界上最受...了解了这些基本概念后,你可以使用“mysql导出工具”来管理和维护你的MySQL数据库,确保数据的安全性和可移植性。在实际操作中,根据具体需求和工具特性调整设置,以达到最佳的导出效果。

    JAVA中文乱码深度分析

    - 数据库连接:在连接数据库时,配置正确的字符集,如MySQL的`useUnicode=true&characterEncoding=UTF-8`。 总的来说,理解Java中的中文问题涉及到对Unicode、系统编码、文件编码以及网络传输编码的深刻认识,通过...

    基于某某平台的数据源迁移oracle -mysql

    **1、MySQL 数据库使用 Navicat 插入中文数据显示乱码的问题解决** - 确保数据库、表以及列的字符集设置为支持中文的字符集,如 `utf8` 或 `utf8mb4`。 - 在 MySQL 的配置文件 my.cnf 或 my.ini 中设置正确的字符集...

    java数据库

    例如,对于MySQL数据库,可以使用以下代码加载驱动: ```java Class.forName("com.mysql.jdbc.Driver"); ``` 2. **建立数据库连接** 使用`DriverManager.getConnection()`方法建立与数据库的连接。该方法需要两...

    mysql-connector-java-5.0.7 jdbc 驱动

    总的来说,MySQL Connector/J 5.0.7 JDBC驱动是Java开发中不可或缺的工具,它为Java应用程序与MySQL数据库之间的交互提供了可靠且高效的解决方案。其对中文字符集的良好支持,确保了在处理多语言数据时的准确无误,...

    mysql 5.6 绿色精简版 5Mb

    在安装和使用MySQL时,选择GBK编码是为了更好地处理中文数据,避免出现乱码问题。但GBK不支持Unicode字符集,对于多语言环境可能不适用。如果需要处理其他语言的数据,建议切换到UTF-8编码。 4. **绿色精简版的优势...

    Web应用安全:JavaMySQL的安全连接方法.pptx

    在Java中连接MySQL数据库,可以使用Java Database Connectivity(JDBC)API。首先,需要下载并引入MySQL的驱动包,如mysql-connector-java-8.0.16.jar。对于MySQL 8.0及以上版本,驱动类名已从`...

    PHP5高级应用开发实践 随书源码 (已修正sql.sql乱码)

    在实际的Web开发中,PHP常与MySQL数据库结合,用于数据的存储和检索。"sql.sql"可能包含了创建表、插入数据、更新和查询等操作的示例,读者可以通过运行这些脚本来配合PHP代码进行数据库交互的学习。修正的“sql.sql...

Global site tag (gtag.js) - Google Analytics