寻找有关在本地磁盘上存储数据的想法

时间:2009-12-18 22:19:58

标签: c# .net

我有大量数据存储在XML文件中,173 MB(460万行),我存储在Windows窗体应用程序的工作目录中。它是将数据表写入XML文件的结果。数据表最初是从查询填充到SQL服务器。

我将其存储在本地而不是从服务器请求它的原因是数据请求耗时超过40秒且有时超时并且数据是静态的并且永远不会更改,而且用户可以脱机并且仍然使用数据。

将文件重新加载到数据表中需要20-30秒。我并不太担心从磁盘加载所花费的时间,因为我让用户知道数据正在加载并且耐心等待。但是,我不喜欢XML文件格式,我正在寻找其他磁盘存储的想法。

数据表仅用作集合对象的最终填充的中间人。如果您有吸烟,我希望听到它们。

我希望远离数据库解决方案并倾向于采用二进制文件方法。下面是我的第一次尝试,但是我得到了一个内存不足的例外:

byte[] b = null;

using (MemoryStream stream = new MemoryStream())
{
   BinaryFormatter bformatter = new BinaryFormatter();
   bformatter.Serialize(stream, timeData);
   b = stream.ToArray();
}

using (FileStream fileStream = new
   FileStream("brad.bin", FileMode.Create, FileAccess.Write))
{
   fileStream.Write(b, 0, b.Length);
}

9 个答案:

答案 0 :(得分:11)

我会查看一个紧凑(本地)数据库,例如SQL Server CESQLite。数据库就是为此而设计的。

答案 1 :(得分:5)

SQLite is pretty nice,您可以从各种断开连接的数据库解决方案中进行选择,但这实际上取决于您想要投入的工作以及您拥有的数据集。

答案 2 :(得分:2)

例如,您可以尝试使用SQLite或csv文件。

答案 3 :(得分:2)

如果永远不会更改,为什么不首先提供应用程序安装呢?

您对“永远不会改变”的含义实际意味着什么感到困惑?

对于本地存储解决方案,有很多可供选择,例如SQLite可以让你使用数据库解决方案,即使在本地,也没有任何安装麻烦。

答案 4 :(得分:1)

如果您将数据表用作中间人,然后从那里加载到集合中,那么使用XMLSerialize直接加载到您的集合中呢?跳过中间人会给你一些性能提升。

答案 5 :(得分:1)

为什么应用程序每次都要求整个数据集?如果你正在使用数据库,你应该(imho)对待数据库与你的数据库类似...
- 根据需要请求所需内容

某些操作可能需要比较整个数据库中的不同数据,但这就是SQL的用途。在数据库中执行这些操作,而不是在应用程序中执行。

您是否有一个用例场景,您绝对需要内存中的整个数据集?

答案 6 :(得分:0)

首先......这是一个难看的段落:P

关于您的问题,如果您使用的是.NET,为什么不使用SQL Server Compact(mdf文件)?这就像使用SQL Server一样,但数据存储在一个文件中。

我个人认为这是最好的方式,但如果你想要选择那么我想你可以考虑

  • Excel文件
  • 以逗号分隔的文字文件
  • MS Access数据库

答案 7 :(得分:0)

我也不喜欢XML,但我认为如果数据完全是只读的话就是这样。

我认为您可以将标准XML文本格式的XML文本写入磁盘,尽管您在名称中使用了带有Binary的类。打开它,看看。 (使用dd Unix工具(如果你还没有dd,下载一些Unix工具)来获取前几兆字节的样本文件,在Wordpad中打开它或类似的东西,看看。)

如果您想让人们不易阅读,请考虑使用加密。

修改

如果您的工作站非常专注于这项任务并在RAM中保留173MB的数据,那么通过它而不是摆弄SQL恰好具有商业意义。

答案 8 :(得分:0)

为什么不将数据保留在服务器上并使用一些标准的DataSet缓存?创建返回180Mb数据的查询听起来像设计问题。

我认为对历史趋势更合适的解决方案是仅检索当前显示的那些记录。如果要放大图表的一部分,请仅检索放大的数据。

关于二进制序列化,您应该将直接序列化为FileStream

using (FileStream fileStream = new
   FileStream("brad.bin", FileMode.Create, FileAccess.Write))
{
   new BinaryFormatter().Serialize(fileStream, timeData);
}