管理大量数据-存储过程或者数据集或者其他...?
我有一个应用程序,每天导入大量数据,数十万条记录。
数据来自不同的来源。使用C#读取数据,然后将其批量插入数据库中。
然后处理以下数据:
- 不同的表被链接
- 生成新表
- 使用复杂的算法校正数据(某些表的总和必须为零)
此处理的大部分是在存储过程中完成的。
尽管在C#中某些复杂的处理会更简单,但是将数据提取到数据集中并重新注入会大大降低速度。
我们可能会问为什么在将数据插入数据库之前我不处理数据,但是我认为操作内存中的100,000条记录不切实际,并且基于SQL集的命令在创建大量记录时会有所帮助。
这可能会引发使用存储过程及其优缺点的古老问题。
(例如,如何对存储过程进行单元测试?)
我想回应的是,我们在处理大量数据方面的经验以及如何解决该问题。
解决方案
回答
我将使用SSIS或者DTS(假设我们正在谈论MSSQL)。它们是为此目的而制造的,并且在需要时可以与SP一起使用。
另一个选择是使用Perl预处理数据。即使听起来像一个奇怪的建议,Perl在这些情况下实际上也非常快。我过去曾用它在合理的时间(即几天而不是几周)内处理数十亿条记录。
关于"如何对存储过程进行单元测试",我们可以像其他任何操作一样使用MBUnit对它们进行单元测试。仅有一点建议:数据的设置和回滚可能很棘手,我们可以使用DTS事务或者显式SQL语句。
回答
在MSSQL中做事时,我通常必须同意Skliwz。 SSIS和DTS是必经之路,但是如果我们不熟悉这些技术,那么使用它们可能会很麻烦。但是,有一种替代方法可以允许我们使用C#进行处理,并且仍将数据保留在SQL Server中。
如果我们真的认为在Cthen中处理会更简单,则可以考虑使用SQL Server Project使用C#创建数据库对象。我们可以使用SQL Server内部的CLR对象执行许多非常强大的操作,这将使我们可以在代码接触数据库之前编写和进行单元测试。我们可以使用任何标准的单元测试框架(NUnit,MSTest)在VS中对CLR代码进行单元测试,而不必编写一堆难以管理的设置和拆卸脚本。
至于测试存储过程,我会坦诚地考虑使用DBFit。数据库不必再成为未经测试的黑洞了:)
回答
处理数据的位置在很大程度上取决于我们正在执行的操作。例如,如果我们需要丢弃数据库中不需要的数据,则可以在Ccode中进行处理。但是,数据库中要处理的数据通常应该是"实现不可知"的数据。因此,如果其他人想要从Java客户端插入数据,则数据库应该能够拒绝不良数据。如果将这种逻辑放入Ccode,Java代码将一无所知。
有人反对说:"但是我永远不会在数据库中使用其他语言!"即使是这样,我们仍然会有DBA或者开发人员使用数据库,并且如果逻辑不存在,他们也会出错。否则,新Cdeveloper会尝试填充数据,而不知道(或者只是忽略)用C#编写的数据预处理器。
简而言之,我们放入数据库中的逻辑应该足以确保数据正确而无需依赖外部软件。