如何解决读取文件并将其写入DB
| 昨天在一次采访中有人问我这个问题,我提供的答案似乎并没有给采访者留下深刻的印象。 :( 这是场景...文件在换行符分隔的记录中具有逗号分隔的属性值。要求此文件必须进入具有匹配列顺序的数据库表中。该文件具有一个自引用列,即,一列\“ Id \”保留该记录的唯一的非null ID,而另一列\“ LinkId \”包含其他记录的ID。该值可以为空。 要求:必须以相同的顺序将文件插入数据库中,但是要一次全部!这意味着没有多个插入。 问题:如何在.Net框架中最好地实现这一点(您可以使用最新的4.0框架) 我提供的解决方案:逐行读取文件并将其解析为所需的XML。然后使用DataTable.readxml()调用将文件立即加载到数据表中,并提交保存该数据表的数据集。 挑战: 100 GB的文本文件呢?这样行吗?功能会变慢多少?如果我们必须将XML保留到内存中以容纳100 GB的数据,系统的虚拟地址空间会支持吗?页面交换会导致问题并变得缓慢吗? DataTable.readxml()是否可用于如此庞大的XML?数据集可以提交吗? 我的答案: :-/ 有想法吗? 谢谢 ish。解决方法
如果您使用的是SQL Server,则可以使用BULK INSERT命令
http://msdn.microsoft.com/en-us/library/ms188365.aspx
基本上,您设置了一个SQLCommand对象,将CommandText设置为类似以下内容:
sqlCommand.CommandText = \"BULK INSERT \" & tableName & \" FROM \'\" & file & \"\' WITH(TABLOCK,FIELDTERMINATOR=\',\')
sqlCommand.ExecuteNonQuery()
tableName-是要插入的表的名称。
文件-是您要SQL Server读取的文件的名称。您需要确保SQL Server可以到达文件存储的位置。这包括ACL权限和网络连接。
BULK INSERT命令有很多选项,我过去使用过它,而且效果很好。
, 无论如何,您将需要进行多次插入。如果文件不是太大,最简单的方法是先创建数据库事务,然后逐行读取并每行创建一个插入命令。读取所有行后,即可提交事务。
对于100GB的文本文件,我首先将其分解为小得多的块以进行插入。也许每1000行提交一次交易?
\“ Id \”和\“ LinkId \”字段对我来说就像是经典的Parent> Child关系。因此,只要先插入父项,就不会有问题。
您没有提到数据库的类型,但是如果是MSSQL,则还可以使用Linq to Sql在每行中创建一个新对象并将其添加到列表中。假设您使用的是C#,则可以使用:
List<YourObject> YourList = new List<YourObject>();
using(System.IO.StreamReader file = new System.IO.StreamReader(\"C:\\yourstorage.txt\")) {
while((line = file.ReadLine()) != null) {
string[] fields = line.Split(\',\');
YourObject obj = new YourObject();
obj.FieldX = fields[0];
obj.FieldY = fields[1];
obj.FieldZ = fields[2];
YourList.Add(obj);
}
}
using(YourDataContext db = new YourDataContext()) {
db.YourObjects.InsertAllOnSubmit(YourList);
db.SubmitChanges();
}
其中,YourObject是已经添加到项目中的Linq to Sql模型,而YourObjects是数据库中的实际表名。但这对于一个大文件可能会占用大量内存。
, 显然,您可以使用OLEDB打开CSV文件,例如,请参见此文件,从那里将数据从一个DB传递到另一个DB应该很容易。
我不确定它是否真正解决了内存问题,但是比在内存中构造XML副本要好得多。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。