如何在java或php中解析一个非常大的xml文件并插入到mysql DB中

我正在尝试将一个庞大的xml文件解析到我的MySQL数据库中。 该文件是4.7gb。 我知道,它疯了。

数据来自这里: http : //www.discogs.com/data/ (最新专辑xml是700mb压缩和4.7gb解压缩)

我可以使用java或php来解析和更新数据库。 我认为java是更聪明的想法。

我需要找到一种方法来解析xml而不填充我的4gb ram,并将其加载到db中。

这样做最聪明的方法是什么? 我听说过SAX解析器,我在想正确的方向吗?

现在,我不关心从这些url下载图像,我只想要数据库中的数据。 我还没有设计表格,但我现在对xml方面更感兴趣。

我使用php的fread()来打开文件的前1000个叮咬,所以至少我可以看到它的样子,这里是文件中第一张专辑结构的样本:

          Persuader, The   Stockholm   

谢谢。

我前段时间遇到类似的问题。 这里是导入大约28MB文件的脚本巫婆的一部分,而不是将整个数据读入内存。 它可能应该工作:)。 它由XML节点读取,在内存中只保留XML的一小部分。 脚本需要很少的修改来满足您的需求。

 $reader = new XMLReader(); $reader->open(); while ($reader->read()) { switch ($reader->nodeType) { case (XMLREADER::ELEMENT): if ($reader->localName == "Table") { $node = $reader->expand(); $dom = new DomDocument(); $n = $dom->importNode($node,true); $dom->appendChild($n); $sxe = simplexml_import_dom($n); $Data = array(); $DataColumns = array(); foreach ($columns as $key => $column) { if (in_array($key,$DateColumns)) { $DateArray = explode('/',substr(trim($sxe->$column),0,10)); $ValueColumn = date('Ymd H:i:s',mktime(0,0,0,$DateArray[1],$DateArray[0],$DateArray[2])); $Data[] = '\''.$ValueColumn.'\''; $DataColumns[] = $key; if ($SplitDateInsert == 'enabled') { $Data[] = '\''.$DateArray[2].'\''; $Data[] = '\''.$DateArray[1].'\''; $Data[] = '\''.$DateArray[0].'\''; $DataColumns[] = $key.'_year'; $DataColumns[] = $key.'_month'; $DataColumns[] = $key.'_day'; } } else { $ValueColumn = addslashes(trim($sxe->$column)); $Data[] = '\''.$ValueColumn.'\''; $DataColumns[] = $key; } } $SQL = "INSERT INTO {$tableName} (".implode(',',$DataColumns).") VALUES (".implode(',',$Data).")"; $db->query($SQL); } // END IF table } } 

你显然需要一个流式API,而不是一个DOM,它需要将整个文档保存在内存中。 Java支持SAX和Stax 。 我自己从未使用过Stax,但听说它比SAX更容易使用,同时仍然高效。

确保将工作拆分为许多事务:数据库将无法在单个事务中支持尽可能多的插入语句。

如果我在哪里使用PHP解析它,我会分两步完成:

  1. 每隔几个点分割文件,并使该minifile成为有效的XML。
  2. 分别解析每个结果文件

如果速度不重要,那么PHP实际上会更好,因为在PHP中解析文本/ XML很容易。

假设MySQL在这方面具有类似Oracle的function,为什么不让DB处理解析呢? 在oracle中,你可以只注册XMLSchema,创建一个结构化的XMLType表(可能比clob更有用),然后插入文件。

从来没有将它用于任何相当大的东西,但我不明白为什么它不应该工作,而且只需几行代码即可完成。 您只需要具有MySQL经验的人来讲述详细信息的工作原理。

我建议在Java上使用Stax。 或者,更简单的是, StaxMate为访问增加了更多便利。

但是你究竟需要用XML做什么? 要在数据库中流式传输它,有一些方法可以将BLOB作为流处理(尽管mySQL JDBC驱动程序因怪癖而臭名昭着),所以这应该是可行的。

4.7 GB不是疯狂的,只是轻微的。 如果您使用的是64位Java,则扩展的VTD-XML应该是最有效且易于使用的选项。

您还没有说过要对XML进行哪些处理。 您可以考虑使用Saxon的流模式XSLT(它需要Saxon-EE产品,这需要花钱) – 如果处理本质上是一个“突发模式流”练习依次处理每个“释放”元素,那么它应该’太难了。 当然,您也可以使用低级SAX或StaX解析,但这几乎肯定需要开发和调试更多的代码。