如何将 Text, XML, CSV 数据文件导入 MySQL

时间:2022-05-03
本文章向大家介绍如何将 Text, XML, CSV 数据文件导入 MySQL,主要内容包括1. 将Text文件(包括CSV文件)导入MySQL、2. 将XML文件导入MySQL、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

原文出处: freenik@Jianshu

将 外部数据导入(import)数据库是在数据库应用中一个很常见的需求。其实这就是在数据的管理和操作中的ETL (Extract, transform, load)的L (Load)部分,也就是说,将特定结构(structure)或者格式(format)的数据导入某个目的地(比如数据库,这里我们讨论MySQL)。

本文要讨论的内容,是如何方便地将多种格式(JSON, Text, XML, CSV)的数据导入MySQL之中。

本文大纲

  1. 将Text文件(包括CSV文件)导入MySQL
  2. 将XML文件导入MySQL
  3. 将JSON文件导入MySQL
  4. 使用MySQL workbench的Table Data Export and Import Wizard进行JSON或CSV文件的导入导出

1. 将Text文件(包括CSV文件)导入MySQL

这里我们的讨论是基于一个假定,Text file和CSV file是有着比较规范的格式的(properly formatted),比如说每行的每个数据域(field)之间是由一个共同的分隔符(比如tab: t)分隔的。

那么首先,你需要根据你的数据的格式(有哪些域),来设计好数据库的对应的表 (的Schema)。

举个例子,要处理的Text文件或者CSV文件是以t作为分隔符的,每行有id, name, balance这么三个数据域,那么首先我们需要在数据库中创建这个表:

CREATE TABLE sometable(id INT, name VARCHAR(255), balance DECIMAL(8,4));

创建成功以后就可以导入了。操作方式很简单:

LOAD DATA LOCAL INFILE '你的文件路径(如~/file.csv)' INTO TABLE sometable FIELDS TERMINATED BY 't' [ENCLOSED BY '"'(可选)] LINES TERMINATED BY 'n' (id, name, balance)

这里要注意的是,我们需要开启local-infile这个MySQL的配置参数,才能够成功导入。究其原因,从MySQL的Manual中可以看到这么一段话:

LOCAL works only if your server and your client both have been configured to permit it. For example, if mysqld was started with –local-infile=0, LOCAL does not work. See Section 6.1.6, “Security Issues with LOAD DATA LOCAL”.

这是MySQL出于安全考虑的默认配置。因此,我们需要在配置文件my.cnf中(以Debian发行版的Linux, 如Ubuntu为例, 即是在/etc/my.cnf中),确保:

local-infile=1

抑或是在命令行启动MySQL时加上–local-infile这一项:

mysql --local-infile -uroot -pyourpwd yourdbname

此外,我们也可以使用MySQL的一个官方导入程序 mysqlimport,这个程序本质上就是为LOAD DATA FILE提供了一个命令行的interface,很容易理解,我们这里就不再详述。

2. 将XML文件导入MySQL

这件事的完成方式,与我们的XML的形式有着很大的关系。

举个例子说,当你的XML数据文件有着很非常规范的格式,比如:

<?xml version="1.0"?>

<row>

<field name="id">1</field>

<field name="name">Free</field>

<field name="balance">2333.3333</field>

</row>

<row>

<field name="id">2</field>

<field name="name">Niki</field>

<field name="balance">1289.2333</field>

</row>

或者

<row column1="value1" column2="value2" .../>

我们就可以很方便使用LOAD XML来导入,这里可以参见MySQL的官方手册–LOAD XML Syntax。 然而我们可能有另外一些需求,比如说,我们可能会想要将XML文件的域映射到不同名字的列(TABLE COLUMN)之中。这里要注意,MySQL v5.0.7以后,MySQL的Stored Procedure中不能再运行LOAD XML INFILE 或者LOAD DATA INFILE。所以转换的程序(procedure)的编写方式与在此之前有所不同。这里,我们需要使用Load_File()和ExtractValue()这两个函数。 以下是一个示例XML文件和程序: 文件:

<?xml version="1.0"?>

<some_list>

<someone id="1" fname="Rob" lname="Gravelle"/>

<someone id="2" fname="Al" lname="Bundy"/>

<someone id="3" fname="Little" lname="Richard"/>

</some_list>

程序:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `import_some_xml`(path varchar(255), node varchar(255))

BEGIN

declare xml_content text;

declare v_row_index int unsigned default 0;

declare v_row_count int unsigned;

declare v_xpath_row varchar(255);

set xml_content = load_file(path);

-- calculate the number of row elements.

set v_row_count = extractValue(xml_content, concat('count(', node, ')'));

-- loop through all the row elements

while v_row_index < v_row_count do

set v_row_index = v_row_index + 1;

set v_xpath_row = concat(node, '[', v_row_index, ']/@*');

insert into applicants values (

extractValue(xml_content, concat(v_xpath_row, '[1]')),

extractValue(xml_content, concat(v_xpath_row, '[2]')),

extractValue(xml_content, concat(v_xpath_row, '[3]'))

);

end while;

END

我们知道MySQL的命令分隔符默认为分号,然而脚本中很显然是有分号的,但是我们并不希望立即执行,所以我们需要临时更改分隔符。