1、数据备份
数据备份是数据库管理员非常重要的工作之一。系统意外崩溃或者硬件的损坏都可能导致数据库的丢失,因此MySQL管理员应该定期地备份数据库,使得在意外情况发生时,尽可能减少损失。
1.1、使用MySQLdump命令备份
MySQLdump是MySQL提供的一个非常有用的数据库备份工具。MySQLdump命令执行时,可以将数据库备份成一个文本文件,该文件中实际包含了多个CREATE和INSERT语句,使用这些语句可以重新创建表和插入数据。
MySQLdump备份数据库语句的基本语法格式如下:
mysqldump –u user –h host –ppassword dbname[tbname, [tbname...]]> filename.sql
- user表示用户名称;
- host表示登录用户的主机名称;
- password为登录密码;
- dbname为需要备份的数据库名称;
- tbname为dbname数据库中需要备份的数据表,可以指定多个需要备份的表;
- 右箭头符号“>”告诉MySQLdump将备份数据表的定义和数据写入备份文件;
- filename.sql为备份文件的名称。
1.1.1、使用MySQLdump备份单个数据库中的所有表
使用MySQLdump命令备份数据库中的所有表,执行过程如下:
为了更好地理解MySQLdump工具是如何工作的,这里给出一个完整的数据库例子。首先登录MySQL,按下面数据库结构创建booksDB数据库和各个表,并插入数据记录。数据库和表定义如下:
create database booksDB;
use booksDB;
create table books
(
bk_id int not null primary key,
bk_title varchar(50) not null,
copyright year not null
);
insert into books values
(11078, 'Learning MySQL', 2010),
(11033, 'Study Html', 2011),
(11035, 'How to user php', 2003),
(11072, 'Teach yourself javascript', 2005),
(11028, 'Learning C++', 2005),
(11069, 'MySQL professional', 2009),
(11026, 'Guide to MySQL 8.0', 2008),
(11041, 'Inside VC++', 2011);
create table authors
(
auth_id int not null primary key,
auth_name varchar(20),
auth_gender char(1)
);
insert into authors values
(1001, 'WriterX', 'f'),
(1002, 'WriterA', 'f'),
(1003, 'WriterB', 'm'),
(1004, 'WriterC', 'f'),
(1011, 'WriterD', 'f'),
(1012, 'WriterE', 'm'),
(1013, 'WriterF', 'm'),
(1014, 'WriterG', 'f'),
(1015, 'WriterH', 'f');
create table authorbook
(
auth_id int not null,
bk_id int not null,
primary key (auth_id, bk_id),
foreign key (auth_id) references authors (auth_id),
foreign key (bk_id) references books (bk_id)
);
insert into authorbook values
(1001, 11033), (1002, 11035), (1003, 11072),
(1004, 11028), (1011, 11078), (1012, 11026),
(1012, 11041), (1014, 11069);
完成数据插入后打开操作系统命令行输入窗口,输入备份命令如下:
mysqldump -u root -p booksdb > ./booksdb_20190301.sql
这里要保证C盘下backup文件夹存在,否则将提示错误信息:系统找不到指定的路径。
输入密码之后,MySQL便对数据库进行了备份,在C:\backup文件夹下面查看刚才备份过的文件,使用文本查看器打开文件可以看到其部分文件内容大致如下:
-- MySQL dump 10.13 Distrib 5.7.28, for macos10.14 (x86_64)
--
-- Host: gz-cynosdbmysql-grp-0048psl9.sql.tencentcdb.com Database: booksDB
-- ------------------------------------------------------
-- Server version 8.0.30-cynos-3.1.16.006
/*!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 utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;
--
-- GTID state at the beginning of the backup
--
SET @@GLOBAL.GTID_PURGED='03d737ed-6656-11f1-ba9a-00f100004023:1-81599';
--
-- Table structure for table `authorbook`
--
DROP TABLE IF EXISTS `authorbook`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `authorbook` (
`auth_id` int NOT NULL,
`bk_id` int NOT NULL,
PRIMARY KEY (`auth_id`,`bk_id`),
KEY `bk_id` (`bk_id`),
CONSTRAINT `authorbook_ibfk_1` FOREIGN KEY (`auth_id`) REFERENCES `authors` (`auth_id`),
CONSTRAINT `authorbook_ibfk_2` FOREIGN KEY (`bk_id`) REFERENCES `books` (`bk_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
...
...
...
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2026-06-26 21:38:56
可以看到,备份文件包含了一些信息,文件开头首先表明了备份文件使用的MySQLdump工具的版本号;然后是备份账户的名称和主机信息,以及备份的数据库的名称,最后是MySQL服务器的版本号,在这里为8.0.13。
备份文件接下来的部分是一些SET语句,这些语句将一些系统变量值赋给用户定义变量,以确保被恢复的数据库的系统变量和原来备份时的变量相同,例如:
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
该语句将用户定义的变量@old_character_set_client中保存的值赋给实际的系统变量character_set_client。
备份文件中以“–”字符开头的行为注释语句;以“/!”开头、“/”结尾的语句为可执行的MySQL注释,这些语句可以被MySQL执行,但在其他数据库管理系统中将被作为注释忽略,以提高数据库的可移植性。
另外,备份文件开始的一些语句以数字开头,代表的是MySQL版本号,这些语句只有在指定的MySQL版本或者比该版本高的情况下才能执行。例如,40101,表明这些语句只有在MySQL版本号为4.01.01或者更高的条件下才可以被执行。
1.1.2、使用MySQLdump备份数据库中的某个表
在前面MySQLdump语法中介绍过,MySQLdump还可以备份数据中的某个表,其语法格式为:
mysqldump –u user –h host –p dbname [tbname, [tbname...]] > filename.sql
tbname表示数据库中的表名,多个表名之间用空格隔开。
备份表和备份数据库中所有表的语句中不同的地方在于,要在数据库名称dbname之后指定需要备份的表名称。
备份booksDB数据库中的books表,输入语句如下:
mysqldump -u root -p booksDB books > C:/backup/books_20190301.sql
该语句创建名称为books_20190301.sql的备份文件,文件中包含了前面介绍的SET语句等内容,不同的是,该文件只包含books表的CREATE和INSERT语句。
-- MySQL dump 10.13 Distrib 5.7.28, for macos10.14 (x86_64)
--
-- Host: gz-cynosdbmysql-grp-0048psl9.sql.tencentcdb.com Database: booksDB
-- ------------------------------------------------------
-- Server version 8.0.30-cynos-3.1.16.006
/*!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 utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;
--
-- GTID state at the beginning of the backup
--
SET @@GLOBAL.GTID_PURGED='03d737ed-6656-11f1-ba9a-00f100004023:1-81599';
1.1.3、使用MySQLdump备份多个数据库
如果要使用MySQLdump备份多个数据库,就需要使用–databases参数。备份多个数据库的语句格式如下:
mysqldump –u user –h host –p --databases [dbname, [dbname...]] > filename.sql
使用–databases参数之后,必须指定至少一个数据库的名称,多个数据库名称之间用空格隔开。
使用MySQLdump备份booksDB和test_db数据库,输入语句如下:
mysqldump -u root -p --databases booksDB test_db > ./books_testDB_20190301.sql
该语句创建名称为books_testDB_20190301.sql的备份文件,该文件中包含了创建两个数据库booksDB和test_db所必需的所有语句。
另外,使用–all-databases参数可以备份系统中所有的数据库,语句如下:
mysqldump –u user –h host –p --all-databases > filename.sql
使用参数–all-databases时,不需要指定数据库名称。
使用MySQLdump备份服务器中的所有数据库,输入语句如下:
mysqldump -u root -p --all-databases > ./alldbinMySQL.sql
该语句创建名称为alldbinMySQL.sql的备份文件,文件中包含了对系统中所有数据库的备份信息。
如果在服务器上进行备份,并且表均为MyISAM表,就应该考虑使用MySQLhotcopy,因为可以更快地进行备份和恢复。
1.2、直接复制整个数据库目录
因为MySQL表保存为文件方式,所以可以直接复制MySQL数据库的存储目录及文件进行备份。MySQL的数据库目录位置不一定相同:
- 在Windows平台下,MySQL 8.0存放数据库的目录通常默认为“C:\Documents andSettings\All Users\ApplicationData\MySQL\MySQL Server 8.0\data”或者其他用户自定义目录;
- 在Linux平台下,数据库目录位置通常为/var/lib/MySQL/,不同Linux版本下目录会有所不同;
这是一种简单、快速、有效的备份方式。要想保持备份的一致性,备份前需要对相关表执行LOCK TABLES操作,然后对表执行FLUSH TABLES。这样当复制数据库目录中的文件时,允许其他客户继续查询表。需要FLUSH TABLES语句来确保开始备份前将所有激活的索引页写入硬盘。当然,也可以停止MySQL服务再进行备份操作。
这种方法虽然简单,但并不是最好的方法。因为这种方法对InnoDB存储引擎的表不适用。使用这种方法备份的数据最好恢复到相同版本的服务器中,不同的版本可能不兼容。
在MySQL版本号中,第一个数字表示主版本号,主版本号相同的MySQL数据库文件格式相同。
1.3、使用MySQLhotcopy工具快速备份
MySQLhotcopy是一个Perl脚本,最初由TimBunce编写并提供。它使用LOCK TABLES、 FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表最快的途径,但它只能运行在数据库目录所在的机器上,并且只能备份MyISAM类型的表。MySQLhotcopy在UNIX系统中运行。
MySQLhotcopy命令语法格式如下:
mysqlhotcopy db_name_1, ... db_name_n /path/to/new_directory
db_name_1,…,db_name_n分别为需要备份的数据库的名称;/path/to/new_directory指定备份文件目录。
使用MySQLhotcopy备份test_db数据库到/usr/backup目录下,输入语句如下:
mysqlhotcopy -u root –p test /usr/backup
要想执行MySQLhotcopy,必须可以访问备份的表文件,具有那些表的SELECT权限、RELOAD权限(以便能够执行FLUSHTABLES)和LOCK TABLES权限。
MySQLhotcopy只是将表所在的目录复制到另一个位置,只能用于备份MyISAM和ARCHIVE表。备份InnoDB类型的数据表时会出现错误信息。由于它复制本地格式的文件,因此也不能移植到其他硬件或操作系统下。
2、数据恢复
2.1、使用MySQL命令恢复
对于已经备份的包含CREATE、INSERT语句的文本文件,可以使用MySQL命令导入到数据库中。
备份的sql文件中包含CREATE、INSERT语句(有时也会有DROP语句)。MySQL命令可以直接执行文件中的这些语句。其语法如下:
mysql –u user –p [dbname] < filename.sql
- user是执行backup.sql中语句的用户名;
- -p表示输入用户密码;
- dbname是数据库名。如果filename.sql文件为MySQLdump工具创建的包含创建数据库语句的文件,执行的时候不需要指定数据库名。
使用MySQL命令将C:\backup\booksdb_20190301.sql文件中的备份导入到数据库中,输入语句如下:
mysql –u root –p booksDB < C:/backup/booksdb_20190301.sql
执行该语句前,必须先在MySQL服务器中创建booksDB数据库,如果不存在恢复过程将会出错。命令执行成功之后booksdb_20190301.sql文件中的语句就会在指定的数据库中恢复以前的表。
如果已经登录MySQL服务器,还可以使用source命令导入sql文件。source语句语法如下:
source filename
使用root用户登录到服务器,然后使用source导入本地的备份文件booksdb_20190301.sql,输入语句如下:
-- 选择要恢复到的数据库
user booksDB;
--使用source命令导入备份文件
source C:\backup\booksdb_20190301.sql
命令执行后,会列出备份文件booksdb_20190301.sql中每一条语句的执行结果。source命令执行成功后,booksdb_20190301.sql中的语句会全部导入到现有数据库中。
执行source命令前,必须使用use语句选择数据库。不然,恢复过程中会出现“ERROR 1046 (3D000): No database selected”的错误。
2.2、直接复制到数据库目录
如果数据库通过复制数据库文件备份,可以直接复制备份的文件到MySQL数据目录下实现恢复。通过这种方式恢复时,保存备份数据的数据库和待恢复的数据库服务器的主版本号必须相同。而且这种方式只对MyISAM引擎的表有效,对于InnoDB引擎的表不可用。
执行恢复以前关闭MySQL服务,将备份的文件或目录覆盖MySQL的data目录,启动MySQL服务。对于Linux/UNIX操作系统来说,复制完文件需要将文件的用户和组更改为MySQL运行的用户和组,通常用户是MySQL,组也是MySQL。
2.3、MySQLhotcopy快速恢复
MySQLhotcopy备份后的文件也可以用来恢复数据库,在MySQL服务器停止运行时,将备份的数据库文件复制到MySQL存放数据的位置(MySQL的data文件夹),重新启动MySQL服务即可。如果以根用户执行该操作,必须指定数据库文件的所有者,输入语句如下:
chown -R mysql.mysql /var/lib/mysql/dbname
从MySQLhotcopy复制的备份恢复数据库,输入语句如下:
cp -R /usr/backup/test usr/local/mysql/data
执行完该语句,重启服务器,MySQL将恢复到备份状态。
如果需要恢复的数据库已经存在,则在使用DROP语句删除已经存在的数据库之后,恢复才能成功。另外,MySQL不同版本之间必须兼容,恢复之后的数据才可以使用。
3、数据库迁移
数据库迁移就是把数据从一个系统移动到另一个系统上。数据迁移有以下原因:
- 需要安装新的数据库服务器。
- MySQL版本更新。
- 数据库管理系统的变更(如从Microsoft SQL Server迁移到MySQL)。
3.1、相同版本的MySQL数据库之间的迁移
相同版本的MySQL数据库之间的迁移就是在主版本号相同的MySQL数据库之间进行数据库移动。迁移过程其实就是在源数据库备份和目标数据库恢复过程的组合。
在讲解数据库备份和恢复时,已经知道最简单的方式是通过复制数据库文件目录,但是此种方法只适用于MyISAM引擎的表。而对于InnoDB表,不能用直接复制文件的方式备份数据库,因此最常用和最安全的方式是使用MySQLdump命令导出数据,然后在目标数据库服务器使用MySQL命令导入。
将www.abc.com主机上的MySQL数据库全部迁移到www.bcd.com主机上。在www.abc.com主机上执行的命令如下:
mysqldump –h www.bac.com –uroot –ppassword dbname |
mysql –h www.bcd.com –uroot –ppassword
MySQLdump导入的数据直接通过管道符“|”传给MySQL命令导入到主机www.bcd.com数据库中,dbname为需要迁移的数据库名称,如果要迁移全部的数据库,可使用参数–all-databases。
3.2、不同版本的MySQL数据库之间的迁移
因为数据库升级等原因,需要将较旧版本MySQL数据库中的数据迁移到较新版本的数据库中。MySQL服务器升级时,需要先停止服务,然后卸载旧版本,并安装新版的MySQL,这种更新方法很简单,如果想保留旧版本中的用户访问控制信息,就需要备份MySQL中的MySQL数据库,在新版本MySQL安装完成之后,重新读入MySQL备份文件中的信息。
旧版本与新版本的MySQL可能使用不同的默认字符集,例如MySQL 8.0版本之前,默认字符集为latin1,而MySQL 8.0版本默认字符集为utf8mb4。数据库中有中文数据的,迁移过程中需要对默认字符集进行修改,不然可能无法正常显示结果。
新版本会对旧版本有一定兼容性。从旧版本的MySQL向新版本的MySQL迁移时,对于MyISAM引擎的表,可以直接复制数据库文件,也可以使用MySQLhotcopy工具、MySQLdump工具。对于InnoDB引擎的表,一般只能使用MySQLdump将数据导出。然后使用MySQL命令导入到目标服务器上。从新版本向旧版本MySQL迁移数据时要特别小心,最好使用MySQLdump命令导出,然后导入目标数据库中。
3.3、不同数据库之间的迁移
不同类型的数据库之间的迁移,是指把MySQL的数据库转移到其他类型的数据库,例如从MySQL迁移到Oracle,从Oracle迁移到MySQL,从MySQL迁移到SQL Server等。
迁移之前,需要了解不同数据库的架构,比较它们之间的差异。不同数据库中定义相同类型的数据的关键字可能会不同。例如,MySQL中日期字段分为DATE和TIME两种,而Oracle日期字段只有DATE。另外,数据库厂商并没有完全按照SQL标准来设计数据库系统,导致不同的数据库系统的SQL语句有差别。例如,MySQL几乎完全支持标准SQL语言,而Microsoft SQL Server使用的是T-SQL语言,T-SQL中有一些非标准的SQL语句,因此在迁移时必须对这些语句进行语句映射处理。
数据库迁移可以使用一些工具,例如在Windows系统下,可以使用MyODBC实现MySQL和SQL Server之间的迁移。MySQL官方提供的工具MySQL Migration Toolkit也可以在不同数据库间进行数据迁移。
4、表的导出和导入
有时会需要将MySQL数据库中的数据导出到外部存储文件中,MySQL数据库中的数据可以导出成sql文本文件、xml文件或者html文件。同样,这些导出文件也可以导入到MySQL数据库中。
4.1、使用SELECT…INTO OUTFILE导出文本文件
MySQL数据库导出数据时,允许使用包含导出定义的SELECT语句进行数据的导出操作。该文件被创建到服务器主机上,因此必须拥有文件写入权限(FILE权限)才能使用此语法。“SELECT…INTO OUTFILE ‘filename’”形式的SELECT语句可以把被选择的行写入一个文件中,并且filename不能是一个已经存在的文件。SELECT…INTO OUTFILE语句的基本格式如下:
SELECT columnlist
FROM table
WHERE condition
INTO OUTFILE 'filename' [OPTIONS]
-- OPTIONS选项
FIELDS TERMINATED BY 'value'
FIELDS [OPTIONALLY] ENCLOSED BY 'vlaue'
FIELDS ESCAPED BY 'value'
LINES STARTING BY 'value'
LINES TERMINATED BY 'value'
SELECT columnlist FROM table WHEREcondition为一个查询语句,查询结果返回满足指定条件的一条或多条记录;INTO OUTFILE语句的作用就是把前面SELECT语句查询出来的结果导出到名称为“filename”的外部文件中。[OPTIONS]为可选参数选项,OPTIONS部分的语法包括FIELDS和LINES子句,其可能的取值有:FIELDS TERMINATED BY 'value':设置字段之间的分隔字符,可以为单个或多个字符,默认情况下为制表符‘\t’。FIELDS [OPTIONALLY] ENCLOSED BY 'value':设置字段的包围字符,只能为单个字符,若使用了OPTIONALLY则只有CHAR和VERCHAR等字符数据字段被包括。FIELDS ESCAPED BY 'value':设置如何写入或读取特殊字符,只能为单个字符,即设置转义字符,默认值为‘\’。LINES STARTING BY 'value':设置每行数据开头的字符,可以为单个或多个字符,默认情况下不使用任何字符。LINES TERMINATED BY 'value':设置每行数据结尾的字符,可以为单个或多个字符,默认值为‘\n’。
FIELDS和LINES两个子句都是自选的,但是如果两个都被指定了,FIELDS必须位于LINES的前面。
SELECT…INTO OUTFILE语句可以非常快速地把一个表转储到服务器上。如果想要在服务器主机之外的部分客户主机上创建结果文件,不能使用SELECT…INTOOUTFILE。在这种情况下,应该在客户主机上使用比如“MySQL –e “SELECT …” > file_name”的命令来生成文件。
SELECT…INTO OUTFILE是LOAD DATA INFILE的补语。用于语句的OPTIONS部分的语法包括部分FIELDS和LINES子句,这些子句与LOAD DATA INFILE语句同时使用。
使用SELECT…INTO OUTFILE将test_db数据库中的person表中的记录导出到文本文件,输入命令如下:
SELECT * FROM test_db.person INTO OUTFILE './person0.txt';
select * from test_db.person into outfile './person0.txt';
执行后报错信息如下:
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv
option so it cannot execute this statement
## 或
(1227, 'Access denied; you need (at least one of) the FILE privilege(s) for this operation')
这是因为MySQL默认对导出的目录有权限限制,也就是说使用命令行进行导出的时候,需要指定目录进行操作。那么指定的目录是什么呢?
查询指定目录的命令如下:
show global variables like '%secure%';

因为secure_file_priv配置的关系,所以必须导出到C:\ProgramData\MySQL\MySQL Server8.0\Uploads\目录下。如果想自定义导出路径,需要修改my.ini配置文件。打开路径C:\ProgramData\MySQL\MySQL Server 8.0,用记事本打开my.ini,然后搜索到以下代码:
secure-file-priv="C:/ProgramData/MySQL/MySQL Server 8.0/Uploads\"
在上述代码前添加#,然后添加以下内容:
secure-file-priv="D:/"

再次使用SELECT…INTO OUTFILE将test_db数据库中person表中的记录导出到文本文件,输入命令如下:
SELECT * FROM test_db.person INTO OUTFILE 'D:/person0.txt';
由于指定了INTO OUTFILE子句,因此SELECT会将查询出来的3个字段值保存到C:\person0.txt文件中。打开文件,内容如下:

默认情况下,MySQL使用制表符“\t”分隔不同的字段,字段没有被其他字符括起来。另外,第5行中有一个字段值为“\N”,表示该字段的值为NULL。默认情况下,如果遇到NULL值,将会返回“\N”,代表空值,其中的反斜线“\”表示转义字符,如果使用ESCAPED BY选项,则N前面为指定的转义字符。
使用SELECT…INTO OUTFILE将test_db数据库person表中的记录导出到文本文件,使用FIELDS选项和LINES选项,要求字段之间使用逗号“,”间隔,所有字段值用双引号括起来,定义转义字符为单引号“\’”,执行的命令如下:
select * from test_db.person
into outfile 'D:/person1.txt"
fields
terminated by ','
enclosed by '\"'
escaped by '\''
lines
terminated by '\r\n';
该语句将把person表中所有记录导入到D盘目录下的person1.txt文本文件中。
FIELDS TERMINATED BY ','表示字段之间用逗号分隔;ENCLOSED BY '"'表示每个字段用双引号括起来;ESCAPED BY ‘’'表示将系统默认的转义字符替换为单引号;LINES TERMINATED BY '\r\n’表示每行以回车换行符结尾,保证每一条记录占一行。
执行成功后,在目录D盘下生成一个person1.txt文件。打开文件,内容如下:
"1","Green","21","Lawyer"
"2","Suse","22","dancer"
"3","Mary","24","Musician"
"4","Willam","20","sports man"
"5","Laura","25",'N'
"6","Evans","27","secretary"
"7","Dale","22","cook"
"8","Edison","28","singer"
"9","Harry","21","magician"
"10","Harriet","19","pianist"
可以看到,所有的字段值都被双引号包括;第5条记录中空值的表示形式为“N”,即使用单引号替换了反斜线转义字符。
使用SELECT…INTO OUTFILE将test_db数据库person表中的记录导出到文本文件,使用LINES选项,要求每行记录以字符串“>”开始、以“”字符串结尾,执行的命令如下:
SELECT * FROM test_db.person INTO OUTFILE "D:/person2.txt"
LINES
STARTING BY '> '
TERMINATED BY '<end>';
执行成功后,在目录D盘下生成一个person2.txt文件。打开文件,内容如下:

可以看到,虽然将所有的字段值导出到文本文件中,但是所有的记录没有分行区分,出现这种情况是因为TERMINATED BY选项替换了系统默认的“\n”换行符,如果希望换行显示,则需要修改导出语句:
SELECT * FROM test_db.person INTO OUTFILE "D:/person3.txt"
LINES
STARTING BY '> '
TERMINATED BY '<end>\r\n';
执行完语句之后,换行显示每条记录,结果如下:

4.2、使用MySQLdump命令导出文本文件
除了使用SELECT… INTO OUTFILE语句导出文本文件之外,还可以使用MySQLdump。本章开始介绍了使用MySQLdump备份数据库,该工具不仅可以将数据导出为包含CREATE、INSERT的sql文件,也可以导出为纯文本文件。
MySQLdump创建一个包含创建表的CREATE TABLE语句的tablename.sql文件和一个包含其数据的tablename.txt文件。MySQLdump导出文本文件的基本语法格式如下:
mysqldump -T path -u root -p dbname [tables] [OPTIONS]
-- OPTIONS选项
--fields-terminated-by=value
--fields-enclosed-by=value
--fields-optionally-enclosed-by=value
--fields-escaped-by=value
--lines-terminated-by=value
- 只有指定了
-T参数才可以导出纯文本文件; path表示导出数据的目录;tables为指定要导出的表名称,如果不指定,将导出数据库dbname中所有的表;[OPTIONS]为可选参数选项,这些选项需要结合-T选项使用。使用OPTIONS常见的取值有:--fields-terminated-by=value:设置字段之间的分隔字符,可以为单个或多个字符,默认情况下为制表符“\t”。--fields-enclosed-by=value:设置字段的包围字符。--fields-optionally-enclosed-by=value:设置字段的包围字符,只能为单个字符,只能包括CHAR和VERCHAR等字符数据字段。--fields-escaped-by=value:控制如何写入或读取特殊字符,只能为单个字符,即设置转义字符,默认值为反斜线“\”。--lines-terminated-by=value:设置每行数据结尾的字符,可以为单个或多个字符,默认值为“\n”。
与SELECT…INTO OUTFILE语句中的OPTIONS各个参数设置不同,这里OPTIONS各个选项等号后面的value值不要用引号括起来。
使用MySQLdump将test_db数据库person表中的记录导出到文本文件,执行的命令如下:
mysqldump -T D:\ test_db person -u root -p
语句执行成功,系统D盘目录下面将会有两个文件,分别为person.sql和person.txt。person.sql包含创建person表的CREATE语句,其内容如下:

person.txt包含数据包中的数据,其内容如下:

使用MySQLdump命令将test_db数据库person表中的记录导出到文本文件,使用FIELDS选项,要求字段之间使用逗号“,”间隔,所有字符类型字段值用双引号括起来,定义转义字符为问号“?”,每行记录以回车换行符“\r\n”结尾,执行的命令如下:
mysqldump -T D:\ test_db person -u root -p --fields-terminated-by=, --fields-optionally-enclosed-by=\" --fields-escaped-by=? --lines-terminated-by=\r\n
上面语句要在一行中输入,语句执行成功,系统D盘目录下面将会有两个文件,分别为person.sql和person.txt。person.sql包含创建person表的CREATE语句,其内容与前面例子中的相同,person.txt文件的内容与上一个例子不同,显示如下:
1,"Green",21,"Lawyer"
2,"Suse",22,"dancer"
3,"Mary",24,"Musician"
4,"Willam",20,"sports man"
5,"Laura",25,?N
6,"Evans",27,"secretary"
7,"Dale",22,"cook"
8,"Edison",28,"singer"
9,"Harry",21,"magician"
10,"Harriet",19,"pianist"
可以看到,只有字符类型的值被双引号括了起来,而数值类型的值没有;第5行记录中的NULL值表示为“?N”,使用问号“?”替代了系统默认的反斜线转义字符“\”。
4.3、使用MySQL命令导出文本文件
MySQL是一个功能丰富的工具命令,使用MySQL还可以在命令行模式下执行SQL指令,将查询结果导入到文本文件中。相比MySQLdump,MySQL工具导出的结果可读性更强。
如果MySQL服务器是单独的机器,用户是在一个client上进行操作,用户要把数据结果导入到client机器上。可以使用MySQL -e语句。
使用MySQL导出数据文本文件语句的基本格式如下:
mysql -u root -p --execute= "SELECT语句" dbname > filename.txt
该命令使用–execute选项,表示执行该选项后面的语句并退出,后面的语句必须用双引号括起来,dbname为要导出的数据库名称;导出的文件中不同列之间使用制表符分隔,第1行包含了各个字段的名称。
使用MySQL语句,导出test_db数据库person表中的记录到文本文件,输入语句如下:
mysql -u root -p --execute="SELECT * FROM person;" test_db > D:\person3.txt
语句执行完毕之后,系统D盘目录下面将会有名称为person3.txt的文本文件,其内容如下:

可以看到,person3.txt文件中包含了每个字段的名称和各条记录,该显示格式与MySQL命令行下SELECT查询结果显示相同。
使用MySQL命令还可以指定查询结果的显示格式,如果某行记录字段很多,可能一行不能完全显示,可以使用–vartical参数,将每条记录分为多行显示。
使用MySQL命令导出test_db数据库person表中的记录到文本文件,使用–vertical参数显示结果,输入语句如下:
mysql -u root -p --vertical --execute="select * from person;" test_db > D:\person4.txt
语句执行之后,D:\person4.txt文件中的内容如下:


可以看到,SELECT的查询结果导出到文本文件之后,显示格式发生了变化,如果person表中记录内容很长,这样显示将会更加容易阅读。
MySQL可以将查询结果导出到html文件中,使用–html选项即可。
使用MySQL命令导出test_db数据库person表中的记录到html文件,输入语句如下:
mysql -u root -p --html --execute="select * from person;" test_db > D:\person5.html
语句执行成功,将在D盘创建文件person5.html,该文件在浏览器中的显示效果如图所示。

如果要将表数据导出到xml文件中,可使用–xml选项。
使用MySQL命令导出test_db数据库中person表中的记录到xml文件,输入语句如下:
mysql -u root -p --xml --execute="SELECT * FROM person;" test_db >D:\person6.xml
语句执行成功,将在D盘创建文件person6.xml,该文件在浏览器中的显示效果如图14.3所示。

4.4、使用LOAD DATA INFILE方式导入文本文件
MySQL允许将数据导出到外部文件,也可以从外部文件导入数据。MySQL提供了一些导入数据的工具,包括LOAD DATA语句、source命令和mysql命令。LOADDATA INFILE语句用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必须为文字字符串。本节将介绍LOAD DATA语句的用法。
LOAD DATA语句的基本格式如下:
LOAD DATA INFILE 'filename.txt' INFO TABLE tablename [OPTIONS] [IGNORE number LINES]
-- OPTIONS 选项
FIELDS TERMINATED BY 'value'
FIELDS ESCAPED BY 'value'
FIELDS ESCAPED BY 'value'
LINES STARTING BY 'value'
LINES TERMINATED BY 'value'
- 可以看到LOAD DATA语句中,关键字INFILE后面的filename文件为导入数据的来源;
- tablename表示待导入 的数据表名称;
- [OPTIONS]为可选参数选项,OPTIONS部分的语法包括FIELDS和LINES子句,其可能的取值有:
FIELDS TERMINATED BY 'value':设置字段之间的分隔字符,可以为单个或多个字符,默认情况下为制表符“\t”。FIELDS [OPTIONALLY] ENCLOSED BY'value':设置字段的包围字符,只能为单个字符。如果使用了OPTIONALLY,则只有CHAR和VERCHAR等字符数据字段被包括。FIELDS ESCAPED BY 'value':控制如何写入或读取特殊字符,只能为单个字符,即设置转义字符,默认值为“\”。LINES STARTING BY 'value':设置每行数据开头的字符,可以为单个或多个字符,默认情况下不使用任何字符。LINES TERMINATED BY 'value':设置每行数据结尾的字符,可以为单个或多个字符,默认值为“\n”。
IGNORE number LINES选项表示忽略文件开始处的行数,number表示忽略的行数。执行LOAD DATA语句需要FILE权限。
使用LOAD DATA命令将D:\person0.txt文件中的数据导入到test_db数据库的person表中,输入语句如下:
LOAD DATA INFILE 'D:\person0.txt' INTO TABLE test_db.person;
恢复之前,要将person表中的数据全部删除。登录MySQL,使用DELETE语句:
mysql> USE test_db;
Database changed;
mysql> DELETE FROM person;
Query OK, 10 rows affected (0.00 sec)
从person0.txt文件中恢复数据,语句如下:

可以看到,语句执行成功之后,原来的数据重新恢复到了person表中。
使用LOAD DATA命令将D:\person1.txt文件中的数据导入到test_db数据库中的person表,使用FIELDS选项和LINES选项,要求字段之间使用逗号“,”间隔,所有字段值用双引号括起来,定义转义字符为单引号“'”,每行记录以回车换行符“\r\n”结尾,输入语句如下:
LOAD DATA INFILE 'D:\person1.txt' INTO TABLE test_db.person
FIELDS
TERMINATED BY ','
ENCLOSED BY '\"'
ESCAPED BY '\''
LINES
TERMINATED BY '\r\n';
恢复之前,使用DELETE语句将person表中的数据全部删除,执行过程如下:
mysql> DELETE FROM person;
Query OK, 10 rows affected (0.00 sec)
从person1.txt文件中恢复数据,执行过程如下:

语句执行成功,使用SELECT语句查看person表中的记录,结果与前一个例子相同。
4.5、使用MySQLimport命令导入文本文件
使用MySQLimport可以导入文本文件,并且不需要登录MySQL客户端。MySQLimport命令提供许多与LOADDATA INFILE语句相同的功能,大多数选项直接对应LOAD DATA INFILE子句。使用MySQLimport语句需要指定所需的选项、导入的数据库名称以及导入的数据文件的路径和名称。MySQLimport命令的基本语法格式如下:
mysqlimport -u root -p dbname filename.txt [OPTIONS]
--OPTIONS 选项
--fields-terminated-by=value
--fields-enclosed-by=value
--feilds-optionally-enclosed-by=value
--fields-escaped-by=value
--lines-terminated-by=value
--ignore-lines=n
dbname为导入的表所在的数据库名称。注意,MySQLimport命令不指定导入数据库的表名称,数据表的名称由导入文件名称确定,即文件名作为表名,导入数据之前该表必须存在。[OPTIONS]为可选参数选项,其常见的取值有:
--fields-terminated-by= 'value':设置字段之间的分隔字符,可以为单个或多个字符,默认情况下为制表符“\t”。--fields-enclosed-by= 'value':设置字段的包围字符。--fields-optionally-enclosed-by='value':设置字段的包围字符,只能为单个字符,包括CHAR和VERCHAR等字符数据字段。--fields-escaped-by= 'value':控制如何写入或读取特殊字符,只能为单个字符,即设置转义字符,默认值为反斜线“\”。--lines-terminated-by= 'value':设置每行数据结尾的字符,可以为单个或多个字符,默认值为“\n”。--ignore-lines=n:忽视数据文件的前n行。
使用MySQLimport命令将D盘目录下的person.txt文件内容导入到test_db数据库中,字段之间使用逗号“,”间隔,字符类型字段值用双引号括起来,将转义字符定义为问号“?”,每行记录以回车换行符“\r\n”结尾,执行的命令如下:
C:\ >mysqlimport -u root -p test_db D:\person.txt --fields-terminated-by=,
--fields-optionally-enclosed-by=\"--fields-escaped-by=?--lines-terminated-by=\
r\n
上面的语句要在一行中输入,语句执行成功,将把person.txt中的数据导入到数据库。
除了前面介绍的几个选项之外,MySQLimport支持许多选项,常见的选项有:
--columns=column_list, -c column_list:采用逗号分隔的列名作为其值。列名的顺序指示如何匹配数据文件列和表列。--compress,-C:压缩在客户端和服务器之间发送的所有信息(如果二者均支持压缩)。-d,--delete:导入文本文件前清空表。--force,-f:忽视错误。例如,某个文本文件的表不存在,继续处理其他文件。不使用–force,如果表不存在,则MySQLimport退出。--host=host_name,-h host_name:将数据导入给定主机上的MySQL服务器。默认主机是localhost。--ignore,-i:参见–replace选项的描述。--ignore-lines=n:忽视数据文件的前n行。--local,-L:从本地客户端读入输入文件。--lock-tables,-l:处理文本文件前锁定所有表,以便写入。这样可以确保所有表在服务器上保持同步。--password[=password],-p[password]:当连接服务器时使用的密码。如果使用短选项形式(-p),选项和密码之间不能有空格。如果在命令行中–password或-p选项后面没有密码值,则提示输入一个密码。--port=port_num,-P port_num:用于连接的TCP/IP端口号。--protocol={TCP | SOCKET | PIPE |MEMORY}:使用的连接协议。--replace,-r --replace和--ignore选项控制复制唯一键值已有记录的输入记录的处理。如果指定–replace,新行替换有相同的唯一键值的已有行;如果指定–ignore,复制已有的唯一键值的输入行被跳过;如果不指定这两个选项,当发现一个复制键值时会出现一个错误,并且忽视文本文件的剩余部分。--silent,-s:沉默模式。只有出现错误时才输出信息。--user=user_name,-u user_name:当连接服务器时MySQL使用的用户名。--verbose,-v:冗长模式。打印出程序操作的详细信息。--version,-V:显示版本信息并退出。
5、常见问题
5.1、MySQLdump备份的文件只能在MySQL中使用吗?
MySQLdump备份的文本文件实际是数据库的一个副本,使用该文件不但可以在MySQL中恢复数据库,而且通过对该文件的简单修改,可以使用该文件在SQL Server或者Sybase等其他数据库中恢复数据库。这在某种程度上实现了数据库之间的迁移。
5.2、如何选择备份工具?
直接复制数据文件是最为直接、快速的备份方法,缺点是基本上不能实现增量备份。备份时必须确保没有使用这些表。如果在复制一个表的同时服务器正在修改它,则复制无效。备份文件时,最好关闭服务器,然后重新启动服务器。为了保证数据的一致性,需要在备份文件前执行以下SQL语句:
FLUSH TABLES WITH READ LOCK;
也就是把内存中的数据都刷新到磁盘中,同时锁定数据表,以保证复制过程中不会有新的数据写入。这种方法备份出来的数据恢复也很简单,直接复制回原来的数据库目录下即可。
MySQLhotcopy是一个PERL程序,它使用LOCKTABLES、FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表最快的途径,但它只能运行在数据库文件所在的机器上,并且MySQLhotcopy只能用于备份MyISAM表。MySQLhotcopy适合于小型数据库的备份,数据量不大,可以使用MySQLhotcopy程序每天进行一次完全备份。
MySQLdump将数据表导成SQL脚本文件,在不同的MySQL版本之间升级时相对比较合适,这也是最常用的备份方法。MySQLdump比直接复制要慢些。
5.3、使用MySQLdump备份整个数据库成功,把表和数据库都删除了,但使用备份文件却不能恢复数据库。
出现这种情况,是因为备份的时候没有指定–databases参数。默认情况下,如果只指定数据库名称,MySQLdump备份的是数据库中所有的表,而不包括数据库的创建语句,例如:
mysqldump -u root -p booksDB > c:\backup\booksDB_20160101.sql
该语句只备份了booksDB数据库下所有的表,打开该文件,可以看到文件中不包含创建booksDB数据库的CREATE DATABASE语句,因此如果把booksDB也删除了,使用该sql文件不能恢复以前的表,恢复时会出现ERROR 1046 (3D000): No database selected的错误信息。必须在MySQL命令行下创建booksDB数据库,并使用use语句选择booksDB之后才可以恢复。利用下面的语句,可以在数据库删除之后正常恢复备份时的状态。
mysqldump -u root -p --databases booksDB > C:\backup\books_DB_20160101.sql
该语句不仅备份了所有数据库下的表结构,还包括创建数据库的语句。

2805

被折叠的 条评论
为什么被折叠?



