如何在不将csv保存到磁盘的情况下将csv格式的数据从内存发送到数据库?

时间:2017-08-16 17:06:57

标签: mysql .net json f# mariadb

我正在组建一个从Quandl收集数据并将其存储在数据库中的系统。我应该注意到,我正在做的事情没有商业方面(我没有客户/雇主)。我这样做是为了一个爱好,并希望学到一两件事。

无论如何,我自己设定的挑战是构建一个自动从Quandl下载数据并将其存储在数据库中的系统,而不必将zip或csv文件保存到磁盘。

Quandl提供每日“delta”文件,可以下载为zip文件。 zip文件被解压缩到csv文件。我已经成功地下载了zip文件,并使用.Net中的MemoryStream,ZipArchive和StreamReader提取内存中的csv文件(特别是F# - 如果需要,很乐意提供代码片段)。

现在我遇到的挑战是如何将其转移到我的数据库中。我使用的数据库是MariaDB(与MySQL基本相同)。我正在使用它,因为这是我的NAS支持的唯一类型的数据库。

选项

  1. 放弃我永远不会保存到磁盘并将csv保存到磁盘的目标,然后将文件路径传递给存储过程,如this answer所示。
  2. 我可以将csv数据转换为JSON或XML,并将其传递给存储过程,并让服务器将字符串解析为临时表。我在使用SQL Server之前已经这样做了,并假设这里有类似的东西。
  3. 逐行读取csv并逐行传递给数据库。这实际上是一个非选择,因为它会非常慢。
  4. 似乎2是我所知道的最佳选择。是否有更直接的方法不涉及将csv转换为JSON或XML?

1 个答案:

答案 0 :(得分:2)

到目前为止,{p> LOAD DATA INFILE将是最快的方式。但它确实需要您将CSV数据放入文件系统。您可能在设置中有一个临时的,甚至是RAM文件系统来执行此操作。

在dotnet世界中,有一个强大的模块用于从流中读取CSV数据。文件是流的特例。出于历史原因,该模块被调用Microsoft.VisualBasic.FileIO.TextFieldParser。 (它在Visual Basic之外工作正常,它很久以前就有一个名字。)

如果使用此方法,则可以通过在每个事务中插入多行CSV来提高性能。有两种方法可以做到这一点。

一个是多行插入,如此

     INSERT INTO tbl 
     (col,col,col)
     VALUES 
     (val, val, val),
     (val, val, val),
     (val, val, val),
     ...
     (val, val, val);

另一种方法是使用START TRANSACTION,然后执行几百次插入,然后执行COMMIT,然后重复此操作直到完成为止。经验教导将使您的插入合理快速。

在MySQL存储过程中解析JSON?非常难以调试。而且,你仍然需要像我提到的那样管理交易。