高效地分析大量数据的方法?

10

我需要分析数万行数据,这些数据从文本文件中导入。每一行数据有八个变量。目前,我使用一个类来定义数据结构。当我遍历文本文件时,我将每行对象存储在一个通用列表(List)中。

我在思考是否应该转向使用关系型数据库(SQL),因为我需要分析每行文本中的数据,并尝试将其与定义术语联系起来,而我目前也是将定义术语存储在通用列表(List)中。

我的目标是使用定义术语翻译大量数据,并使定义过的数据可以进行过滤、搜索等操作。反复思考后,使用数据库似乎更合理,但在做出更改之前,我想先得到更有经验的开发人员的确认(我最初使用的是结构体和数组列表)。

我唯一能想到的缺点是,在用户查看并翻译数据后,这些数据不需要被保留。因此,使用数据库可能有点浪费。

7个回答

3

不一定需要访问数据库,这取决于数据的实际大小和所需处理的过程。如果您将数据加载到具有自定义类的列表中,为什么不使用Linq来查询和过滤呢?类似这样:

var query = from foo in List<Foo>
            where foo.Prop = criteriaVar
            select foo;

真正的问题是数据是否太大,无法舒适地加载到内存中。如果是这种情况,那么使用数据库会更简单。


我正在导入的文件通常包含数万行,有些可以超过10万行。每行都有八个需要分析和翻译的字段。例如,一个字段可能包含值“phy”,需要根据定义文件翻译为“物理层”。我正在尝试找出分析和翻译这些数据的最有效方法。 - Snooze
你打算对数据进行聚合分析,还是仅逐行处理?如果是后者,那么在读取文本文件并边读边处理的情况下,相比于尝试将数据放入 SQL Express 或 Access 中,速度可能会更快。不过,将其放入数据库中将为您提供一定程度的灵活性,例如创建索引的能力,否则您将不得不自己编写代码。 - Thomas
我认为我别无选择,只能进行聚合分析,因为一些定义依赖于文本文件中的先前行。此外,通过聚合分析,我可以重组数据,使其更易读/理解。即使我要实时处理,我仍需要一个数据结构,以便用户可以过滤/搜索数据。 - Snooze
如果您选择迭代方式,那么您将需要分析最佳的内存索引模式。虽然最终可能涉及到List<T>或Dictionary<T,T>,但这意味着您将不得不开发自己的索引方案。鉴于您了解数据,这可能比DBMS索引方案更快,但只有性能测试才能告诉您确切情况。 - Thomas
将对象存储在List<T>中可能已经足够高效了。当今计算机的速度惊人地快。我期望它比任何数据库解决方案都更具性能。过早优化 ... - Joe H
显示剩余2条评论

3

这不是大量数据。我看不出为什么需要在分析中涉及数据库。

C#内置了查询语言--LINQ。原帖作者目前使用的是对象列表,因此实际上没有什么要做的。在这种情况下,对于我来说,加入数据库似乎会增加更多的热度而不是帮助。


对于查询语言,你不必硬编码这些东西(或自己发明)吗? - i_am_jorf
1
@jeffamaphone - C# 中确实内置了一个查询语言 -- LINQ。原帖的发布者目前使用的是对象列表,因此实际上没有什么剩下的事情要做了。在我看来,在这种情况下使用数据库只会增加更多的麻烦而不是收获好处。 - Joe H

1

听起来你需要的是一个数据库。Sqlite 支持 内存数据库(使用“:memory:”作为文件名)。我猜其他一些数据库也可能有内存模式。


这听起来是一个相当有吸引力的解决方案。我对内存数据库不是很熟悉,所以我需要做些研究,但从名字上看,Sqlite听起来像是一个轻量级系统。 - Snooze
1
尽管SQLite备受瞩目,但在处理数百万条数据方面表现并不出色。如果只有几千条数据,我就不知道了,这取决于具体情况。请确保正确建立索引,并尝试使用较大的页面大小。如果你有理由怀疑它的数据量会增长,不要选择SQLite!我基于经验告诉你。 - MPelletier
是的,它很轻便,你得到你所付出的。我用它做一些小事情,还有一些数十万的东西。此外,它并不真正支持多线程安全。 - i_am_jorf

1
我曾经在之前的公司工作时遇到了你现在面临的同样问题。问题是我想要一个具体而好的解决方案来处理大量的条形码生成文件。这些条形码生成了一个包含成千上万条记录的文本文件。对于我来说,操作和呈现数据一开始非常困难。基于记录,我编写了一个读取文件并将数据加载到数据表中并能够保存到数据库的类。我使用的数据库是SQL Server 2005,然后我可以轻松管理已保存的数据并按我喜欢的方式呈现它们。关键是从文件中读取数据并将其保存到数据库中。如果您这样做,将有很多选项可供操作和按您喜欢的方式呈现。

0

如果你不介意使用Access,你可以这样做:

将一个空的Access数据库作为资源附加进来, 需要时,将该数据库写入文件中。 运行一个处理你数据列的CREATE TABLE语句, 将数据导入新的表格中。 使用SQL运行你的计算, 在关闭时删除该Access数据库。

你可以使用Resourcer等程序加载该数据库到Resx文件中。

  ResourceManager res = new ResourceManager( "MyProject.blank_db", this.GetType().Assembly );
  byte[] b = (byte[])res.GetObject( "access.blank" );

然后使用以下代码从项目中提取资源。将字节数组保存到临时位置并使用临时文件名保存。

"MyProject.blank_db"是资源文件的位置和名称 "access.blank"是给资源保存的选项卡


顺便提一下,同样的方法也适用于 SQL Server Compact Edition,它是随 Visual Studio 2008 一起提供的。 - John Saunders
我认为我更愿意使用内存中的SQL解决方案,但我需要进行研究。 - Snooze

0

如果你只需要进行搜索和替换,可以考虑使用sed和awk,并且可以使用grep进行搜索。当然,这仅适用于Unix平台。


在Windows上,msys和cygwin可以提供sed和awk。 - eric.christensen

0
根据您的描述,我认为Linux命令行工具可以很好地处理您的数据。使用数据库可能会使您的工作变得不必要地复杂。如果您正在使用Windows,则可以通过不同的方式使用这些工具。我建议使用Cygwin。以下工具可能涵盖您的任务:sort、grep、cut、awk、sed、join、paste。
这些Unix/Linux命令行工具可能对Windows用户来说看起来很可怕,但是喜欢它们的人有其原因。以下是我喜欢它们的原因:
  1. 它们允许您的技能积累——您对一个工具的部分知识在未来的不同任务中可能会有所帮助。
  2. 它们允许您的努力积累——您用于完成任务的命令行(或脚本)可以在没有人类干预的情况下重复使用多次,适用于不同的数据。
  3. 它们通常比您编写的相同工具表现更出色。如果您不相信,请尝试为千兆字节文件编写比sort更好的版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接