如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?
Posted
技术标签:
【中文标题】如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?【英文标题】:How can I send data in csv format from memory to a database without saving the csv to disk? 【发布时间】:2018-01-24 22:29:41 【问题描述】:我正在组建一个系统,该系统从 Quandl 收集数据并将其存储在数据库中。我应该注意,我所做的事情没有商业方面的意义(我没有客户/雇主)。我这样做是一种爱好,希望能学到一两件事。
无论如何,我为自己设定的挑战是构建一个系统,该系统可以自动从 Quandl 下载数据并将其存储在数据库中,而无需将 zip 或 csv 文件保存到磁盘。
Quandl 提供每日 'delta' 文件,可以下载为 zip 文件。 zip 文件被提取为 csv 文件。我已经设法下载了 zip 文件并将 csv 文件全部提取到内存中,使用 .Net 中的 MemoryStream、ZipArchive 和 StreamReader(特别是 F#——如果需要,很乐意提供代码 sn-p)。
现在我面临的挑战是如何将其转移到我的数据库中。我使用的数据库是 MariaDB(本质上与 mysql 相同)。我使用它是因为这是我的 NAS 支持的唯一数据库类型。
选项是
-
放弃我从不保存到磁盘并将 csv 保存到磁盘的目标,然后将文件路径传递给存储过程,如this answer。
我可以将 csv 数据转换为 JSON 或 XML 并将其传递给存储过程,然后让服务器将字符串解析为临时表。我在使用 SQL Server 之前已经完成了这项工作,并且假设这里也有类似的情况。
逐行读取csv并逐行传递给数据库。这确实是一个不可选项,因为它会非常慢。
似乎 2 是我所知道的最佳选择。有没有更直接的方法,不涉及将 csv 转换为 JSON 或 XML?
【问题讨论】:
这篇博文有帮助吗? medium.com/@edgarsanchezg/… @TomasPetricek - 我只阅读了第一段并回过头来说我不敢相信你能找到如此特别针对我的问题的目标!我会阅读其余部分,如果有任何问题,我会告诉你,但看起来很有希望。 【参考方案1】: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?很难调试。而且,您仍然需要像我提到的那样管理交易。
【讨论】:
以上是关于如何在不将 csv 保存到磁盘的情况下将 csv 格式的数据从内存发送到数据库?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不创建架构的情况下将 CSV 文件加载到 BigQuery