17.4 表的导出和导入
有时会需要将MySQL数据库中的数据导出到外部存储文件中,MySQL数据库中的数据可以导出成sql文本文件、xml文件或者html文件。同样这些导出文件也可以导入到MySQL数据库中。本节将介绍数据导出导入的常用方法。
17.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 'value' FIELDS ESCAPED BY 'value' LINES STARTING BY 'value' LINES TERMINATED BY 'value'
可以看到SELECT columnlist FROM table WHERE condition为一个查询语句,查询结果返回满足指定条件的一条或多条记录;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...INTO OUTFILE。在这种情况下,应该在客户主机上使用如mysql –e "SELECT ..." > file_name的命令,来生成文件。
SELECT...INTO OUTFILE是LOAD DATA INFILE的补语;用于语句的OPTIONS部分的语法包括部分FIELDS和LINES子句,这些子句与LOAD DATA INFILE语句同时使用。
【例17.10】使用SELECT...INTO OUTFILE将test_db数据库的person表中的记录导出到文本文件,输入命令如下:
mysql> SELECT * FROM test_db.person INTO OUTFILE "C:/person0.txt";
由于指定了INTO OUTFILE子句,SELECT将查询出来的字段的值保存到C:\person0.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
可以看到默认情况下,MySQL使用制表符‘\t’分隔不同的字段,字段没有被其他字符括起来。另外,在Windows平台下,使用记事本打开该文件,读者可能发现,显示格式与这里并不相同,这是因为Windows系统下回车换行符为‘\r\n’,而MySQL中默认换行符为‘\n’,因此会在person.txt中可能看到类似黑色方块的字符,所有的记录也会在同一行显示。
另外,注意到第5行中有一个字段值为‘\N’,这表示该字段的值为NULL。默认情况下,如果遇到NULL值,将会返回‘\N’(代表空值)。反斜线‘\’表示转义字符,如果使用ESCAPED BY选项,则N前面为指定的转义字符。
【例17.11】使用SELECT...INTO OUTFILE将test_db数据库中的person表中的记录导出到文本文件,使用FIELDS选项和LINES选项,要求字段之间使用逗号间隔,所有字段值用双引号括起来,转义字符定义为单引号‘\'’,执行的命令如下:
SELECT * FROM test_db.person INTO OUTFILE "C:/person1.txt" FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\'' LINES TERMINATED BY '\r\n';
该语句将把person表中所有记录导入到C盘目录下的person1.txt文件中。
FIELDS TERMINATED BY ','表示字段之间用逗号分隔;ENCLOSED BY '\"'表示每个字段用双引号括起来;ESCAPED BY '\''表示将系统默认的转义字符替换为单引号;LINES TERMINATED BY '\r\n'表示每行以回车换行符结尾,保证每一条记录占一行。
执行成功后,在C盘目录下生成一个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’,即使用单引号替换了反斜线转义字符。
【例17.12】使用SELECT...INTO OUTFILE将test_db数据库中的person表中的记录导出到文本文件,使用LINES选项,要求每行记录以字符串“> ”开始,以“<end>”字符串结尾,执行的命令如下:
SELECT * FROM test_db.person INTO OUTFILE "C:/person2.txt" LINES STARTING BY '> ' TERMINATED BY '<end>';
执行成功后,在C盘目录下生成一个person2.txt文件,打开文件内容如下:
> 1 Green 21 Lawyer <end>> 2 Suse 22 dancer <end>> 3 Mary 24 Musician <end>> 4 Willam 20 sports man <end>> 5 Laura 25 \N <end>> 6 Evans 27 secretary <end>> 7 Dale 22 cook <end>> 8 Edison 28 singer <end>> 9 Harry 21 magician <end>> 10 Harriet 19 pianist <end>
可以看到,虽然将所有的字段值导出到文本文件中,但是所有的记录没有分行区分,出现这种情况是因为TERMINATED BY选项替换了系统默认的‘\n’换行符,如果希望换行显示,则需要修改导出语句,输入下面语句:
SELECT * FROM test_db.person INTO OUTFILE "C:/person2.txt" LINES STARTING BY '> ' TERMINATED BY '<end>\r\n';
执行完语句之后,换行显示每条记录,结果如下:
> 1 Green 21 Lawyer <end> > 2 Suse 22 dancer <end> > 3 Mary 24 Musician <end> > 4 Willam 20 sports man <end> > 5 Laura 25 \N <end> > 6 Evans 27 secretary <end> > 7 Dale 22 cook <end> > 8 Edison 28 singer <end> > 9 Harry 21 magician <end> > 10Harriet 19 pianist <end>
17.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选项使用,其常见的取值有以下几种。
•--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值不要用引号括起来。
【例17.13】使用mysqldump将test_db数据库中的person表中的记录导出到文本文件,执行的命令如下:
mysqldump -T C:/ test_db person -u root –p
语句执行成功,系统C盘目录下面将会有两个文件,分别为person.sql和person.txt。person.sql包含创建person表的CREATE语句,其内容如下:
/*!40103 SET TIME_ZONE='+00:00' */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table 'person' -- DROP TABLE IF EXISTS 'person'; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE 'person' ( 'id' int(10) unsigned NOT NULL AUTO_INCREMENT, 'name' char(40) NOT NULL DEFAULT '', 'age' int(11) NOT NULL DEFAULT '0', 'info' char(50) DEFAULT NULL, PRIMARY KEY ('id') ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!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 2011-08-19 15:02:16
备份文件中的信息如17.1.1节介绍。
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
【例17.14】使用mysqldump命令将test_db数据库中的person表中的记录导出到文本文件,使用FIELDS选项,要求字段之间使用逗号间隔,所有字符类型字段值用双引号括起来,转义字符定义为问号‘?’,每行记录以回车换行符“\r\n”结尾,执行的命令如下:
C:\>mysqldump -T C:\backup test_db person -u root -p --fields-terminated-by=, --fields-optionally- enclosed-by= \" --fields-escaped-by=? --lines-terminated-by=\r\n
上面语句要在一行中输入,语句执行成功,系统C:\backup目录下面将会有两个文件,分别为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”,使用问号‘?’替代了系统默认的反斜线转义字符‘\’。
17.4.3 用mysql命令导出文本文件
mysql是一个功能丰富的工具命令。使用mysql还可以在命令行模式下执行SQL指令,将查询结果导入到文本文件中。相比mysqldump,mysql工具导出的结果可读性更强。
如果MySQL服务器是单独的机器,用户是在客户端进行操作,用户要把数据结果导入到客户端,可以使用mysql -e语句。
使用mysql命令导出数据文本文件语句的基本格式如下:
mysql -u root -p --execute=”SELECT语句” dbname > filename.txt
该命令使用--execute选项,表示执行该选项后面的语句并退出,后面的语句必须用双引号括起来,dbname为要导出的数据库名称;导出的文件中不同列之间使用制表符分隔,第一行包含了各个字段的名称。
【例17.15】使用mysql语句导出test_db数据库中person表中的记录到文本文件,输入语句如下:
mysql -u root -p --execute="SELECT * FROM person;" test_db > C:\person3.txt
语句执行完毕之后,系统C盘目录下将会有名称为person3.txt的文本文件,其内容如下:
id name age info 1 Green 21 Lawyer 2 Suse 22 dancer 3 Mary 24 Musician 4 Willam 20 sports man 5 Laura 25 NULL 6 Evans 27 secretary 7 Dale 22 cook 8 Edison 28 singer 9 Harry 21 magician 10 Harriet 19 pianist
可以看到,person3.txt文件中包含了每个字段的名称和各条记录,该显示格式与MySQL命令行下SELECT查询结果显示相同。
使用mysql命令还可以指定查询结果的显示格式,如果某行记录字段很多,可能一行不能完全显示,可以使用--vartical参数,将每条记录分为多行显示。
【例17.16】使用mysql命令导出test_db数据库中person表中的记录到文本文件,使用--vertical参数显示结果,输入语句如下:
mysql -u root -p --vertical --execute="SELECT * FROM person;" test_db > C:\person4.txt
语句执行之后,C:\person4.txt文件中的内容如下:
*************************** 1. row *************************** id: 1 name: Green age: 21 info: Lawyer *************************** 2. row *************************** id: 2 name: Suse age: 22 info: dancer *************************** 3. row *************************** id: 3 name: Mary age: 24 info: Musician *************************** 4. row *************************** id: 4 name: Willam age: 20 info: sports man *************************** 5. row *************************** id: 5 name: Laura age: 25 info: NULL *************************** 6. row *************************** id: 6 name: Evans age: 27 info: secretary *************************** 7. row *************************** id: 7 name: Dale age: 22 info: cook *************************** 8. row *************************** id: 8 name: Edison age: 28 info: singer *************************** 9. row *************************** id: 9 name: Harry age: 21 info: magician *************************** 10. row *************************** id: 10 name: Harriet age: 19 info: pianist
可以看到,SELECT的查询结果导出到文本文件之后,显示格式发生了变化,如果person表中记录内容很长,这样显示将会更加容易阅读。
mysql可以将查询结果导出到HTML文件中,使用--html选项即可。
【例17.17】使用mysql命令导出test_db数据库中person表中的记录到HTML文件,输入语句如下:
mysql -u root -p --html --execute="SELECT * FROM person;" test_db > C:\person5.html
语句执行成功,将在C盘创建文件person5.html,该文件在浏览器中显示如下:
如果要将表数据导出到XML文件中,可使用--xml选项。
【例17.18】使用mysql命令导出test_DB数据库中person表中的记录到XML文件,输入语句如下:
mysql -u root -p --xml --execute="SELECT * FROM person;" test_db > C:\person6.xml
语句执行成功,将在C盘创建文件person6.xml,该文件在浏览器中显示如图17.2所示。
17.4.4 用LOAD DATA INFILE方式导入文本文件
MySQL允许将数据导出到外部文件,也可以将外部文件导入数据库。MySQL提供了一些导入数据的工具,这些工具有LOAD DATA语句、source命令和mysql命令。LOAD DATA INFILE语句用于高速地从一个文本文件中读取行,并装入一个表中。本节将介绍LOAD DATA语句的用法。
LOAD DATA语句的基本格式如下:
LOAD DATA INFILE 'filename.txt' INTO TABLE tablename [OPTIONS] [IGNORE number LINES] -- OPTIONS选项 FIELDS TERMINATED BY 'value' FIELDS [OPTIONALLY] ENCLOSED 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权限。
【例17.19】使用LOAD DATA命令将C:\person0.txt文件中的数据导入到test_db数据库中的person表,输入语句如下:
LOAD DATA INFILE 'C:/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文件中还原数据,语句如下:
mysql> LOAD DATA INFILE 'C:/person0.txt' INTO TABLE test_db.person;
Query OK, 10 rows affected (0.00 sec)
Records: 10 Deleted: 0 Skipped: 0 Warnings: 0
mysql> SELECT * FROM person;
+---- | +--------- | +----- | +------------+ |
id | name | age | info |
+---- | +--------- | +----- | +------------+ |
1 | Green | 21 | Lawyer |
2 | Suse | 22 | dancer |
3 | Mary | 24 | Musician |
4 | Willam | 20 | sports man |
5 | Laura | 25 | NULL |
6 | Evans | 27 | secretary |
7 | Dale | 22 | cook |
8 | Edison | 28 | singer |
9 | Harry | 21 | magician |
10 | Harriet | 19 | pianist |
+---- | +--------- | +------ | +-------------+ |
10 rows in set (0.00 sec)
可以看到,语句执行成功之后,原来的数据重新恢复到了person表中。
【例17.20】使用LOAD DATA命令将C:\person1.txt文件中的数据导入到test_db数据库中的person表,使用FIELDS选项和LINES选项,要求字段之间使用逗号‘,’间隔,所有字段值用双引号括起来,转义字符定义为单引号‘\'’,输入语句如下:
LOAD DATA INFILE 'C:/person1.txt' INTO TABLE test_db.person FIELDS TERMINATED BY ',' ENCLOSED BY '\"' ESCAPED BY '\'' LINES TERMINATED BY '\r\n';
还原之前,将person表中的数据全部删除,使用DELETE语句,执行过程如下:
mysql> DELETE FROM person; Query OK, 10 rows affected (0.00 sec)
从person1.txt文件中还原数据,执行过程如下:
mysql> LOAD DATA INFILE 'C:/person1.txt' INTO TABLE test_db.person -> FIELDS -> TERMINATED BY ',' -> ENCLOSED BY '\"' -> ESCAPED BY '\'' -> LINES -> TERMINATED BY '\r\n'; Query OK, 10 rows affected (0.00 sec) Records: 10 Deleted: 0 Skipped: 0 Warnings: 0
语句执行成功,使用SELECT语句查看person表中的记录,结果与前一个例子相同。
17.4.5 用mysqlimport命令导入文本文件
mysqlimport可以导入文本文件,使用mysqlimport不需要登录MySQL客户端。mysqlimport命令提供许多与LOAD DATA INFILE语句相同的功能,大多数选项直接对应LOAD DATA INFILE子句。使用mysqlimport语句需要指定所需的选项、导入的数据库名称以及导入的数据文件的路径和名称。mysqlimport命令的基本语法格式如下:
mysqlimport –u root –p dbname filename.txt [OPTIONS] --OPTIONS 选项 --fields-terminated-by= 'value' --fields-enclosed-by= 'value' --fields-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行。
【例17.21】使用mysqlimport命令将C:\backup目录下的person.txt文件内容导入到test_db数据库中,字段之间使用逗号‘,’间隔,字符类型字段值用双引号括起来,转义字符定义为问号‘?’,每行记录以回车换行符“\r\n”结尾,执行的命令如下:
C:\ >mysqlimport -u root -p test_db C:/backup/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:显示版本信息并退出。