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

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

Quandl 提供每日 'delta' 文件,可以下载为 zip 文件。 zip 文件被提取为 csv 文件。我已经设法下载 zip 文件并将 csv 文件全部提取到内存中,使用 .Net 中的 MemoryStream、ZipArchive 和 StreamReader(特别是 F# - 如果需要,很乐意提供代码片段)。

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

选项是

  • 放弃我永远不保存到磁盘的目标,将 csv 保存到磁盘,然后将文件路径传递给存储过程,如 this answer
  • 我可以将 csv 数据转换为 JSON 或 XML 并将其传递给存储过程,并让服务器将字符串解析为临时表。我在使用 SQL Server 之前已经这样做了,并且我假设这里可能有类似的事情。
  • 逐行读取csv并逐行传递给数据库。这确实是一个不可选项,因为它会非常慢。

  • 似乎 2 是我所知道的最佳选择。是否有更直接的方法不涉及将 csv 转换为 JSON 或 XML?

    最佳答案

    到目前为止,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?异常难以调试。而且,您仍然需要像我提到的那样管理事务。

    关于mysql - 如何将 csv 格式的数据从内存发送到数据库而不将 csv 保存到磁盘?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45719328/

    10-11 23:05
    查看更多