版本控制友好,可扩展的二进制文件格式

时间:2010-03-29 20:33:11

标签: .net binary file-format

在我正在进行的项目中,需要将大量的数据结构保存到磁盘(编辑:想想几十MB)。作为一个乐观主义者,我认为必须有一个标准的解决方案来解决这个问题;但是,到目前为止,我还没有找到满足以下要求的解决方案:

  1. .NET 2.0支持,最好使用FOSS实现
  2. 版本友好(这应解释为:如果底层数据结构中的更改很简单,例如添加/删除字段,则读取旧版本的格式应该相对简单)
  3. 能够进行某种形式的随机访问,其中部分数据可以在初始创建后进行扩展,而无需对此时创建的集合进行反序列化(将其视为扩展中间结果)
  4. 节省空间和时间(根据此要求,XML已被排除在外)
  5. 到目前为止考虑的选项:

    非常感谢任何建议或指示。此外,如果您认为上述任何信息都不正确,请提供指示/示例以证明我的错误。

7 个答案:

答案 0 :(得分:6)

您是否考虑过使用SQL Server Compact Edition

  1. 它有很多.NET支持
  2. 模式的版本控制以及处理旧模式的应用程序的新版本的能力将完全由您控制。除了旧版本中不存在的较新版本的功能之外,SQL Server Compact的版本控制在您的应用程序之外应该是有些无用的。
  3. 您可以使用大部分SQL语法进行查询。
  4. 显然,从这个名称来看,这个版本的SQL Server是为嵌入式系统设计的,其中包括希望避免安装SQL Express或完整版SQL Server的应用程序。
  5. 现在,这会遇到与SQLite相同的问题,因为您告诉我们的数据结构可能会变得复杂,但即使您使用自己的二进制格式也是如此。

    不过,在我看来,你还没有弄明白“大小”到底是什么意思。如果“sizeable”意味着接近或超过4 GB,显然SQL Compact将不起作用,也不会有许多其他数据库文件格式。

    编辑我注意到您在帖子后添加了SQL Compact Edition到“太重量级”列表中。 SQL Compact仅需要5MB的RAM和2MB的磁盘存储空间,具体取决于数据库的大小。所以,问题不能是重量级的。现在,关于声称数据结构的第二点将非常复杂。如果这是真的,我怀疑任何关系数据库产品都是如此,滚动你自己的二进制格式将更加复杂。鉴于此,您可能会查看非关系数据库产品,例如mongodb

答案 1 :(得分:1)

你会考虑(B)JSON吗?如果是这样,其中一个面向文档的数据库可能符合您的需求。 CouchDB是一个带有REST API的JSON文档存储(绝对可以从.Net中使用)。 CouchDB文档可以有二进制附件,我已经与那些在文档中存储多MB附件而没有问题的人交谈过。我相信MongoDB,一个使用二进制JSON作为存储格式的替代文档数据库,也有.Net绑定。

这些“NoSQL”替代品很容易被版本化,因为它们基本上没有架构。 JSON非常紧凑,它们肯定允许更新现有数据。

答案 2 :(得分:1)

您是否考虑过db4o之类的内容?许可可能会限制您,但它似乎符合该法案。

答案 3 :(得分:1)

这是一个有趣的选择:思科的ETCH,在Apache许可下可用(您不需要支付版税,而且您的软件仍然是商业版和您的软件。)

这个想法是使用Etch以二进制形式在系统组件之间进行通信。该格式对版本更改具有弹性,并且可以根据您的需求状态处理缺少的字段等。

好处是您可以在二进制格式之上获得更完整的传输系统。它被认为非常快(一台机器每秒执行900次SOAP XML事务,产生50,000次ETCH事务)。

如果需要多个索引,可以将二值化表单存储在轻量级RDBMS中。如果只有一个索引就足够了,那么一个简单的键/值存储(CouchDB / MongoDB甚至是分布式环境的Cassandra)也会给你带来很棒的存储性能!

答案 4 :(得分:0)

你看过二进制序列化吗?

有关详细信息,请参阅我的帖子here。它有示例代码来序列化Dictionary对象中包含的自定义类。不确定你的结构有多复杂,但是根据你的需要调整它应该非常简单。

如果您需要更多帮助,请添加评论...

答案 5 :(得分:0)

如果XML因空间消耗而无法满足要求,则可以通过System.IO.Compression.DeflateStream提供XML以减小其大小。 Deflate算法与GZip压缩基本相同,但速度可提高40%(请参阅Jeff Atwood's blog)。

答案 6 :(得分:0)

我不会这么快就注销Protocol Buffers。当然,您引用的手动输入表示兆字节的顺序,并且您正在处理数十兆字节......但您是否尝试过研究以确定此限制是否会影响您?

如果它仍然影响你,我的建议是采用混合方法:将数据集切片并切成1 MB大小的块,然后将每个块存储为SQLite表的字段(作为二进制blob) 。将其他字段添加到表中以查找要在其上编制索引(或按其搜索)的元素。

是的,它增加了复杂性,但似乎没有别的东西可以让你接近你需要去的地方。