2010-03-29 73 views
12

在我目前正在研究的項目中,需要將相當大的數據結構保存到磁盤(編輯:想幾十MB)。作爲一個樂觀主義者,我認爲對於這樣一個問題必須有一個標準的解決方案。然而,到現在爲止我還沒有找到滿足以下要求的解決方案:版本控制友好的,可擴展的二進制文件格式

  1. .NET 2.0的支持,最好用FOSS實施
  2. 友好的版本(這應該被解釋爲:閱讀舊版本的格式應該相對簡單,如果基礎數據結構的變化很簡單,比如添加/刪除字段)
  3. 能夠做某種形式的隨機訪問,其中部分數據可以在初始創建之後進行擴展,而不需要將此時創建的集合反序列化(將此視爲擴展中間結果)
  4. 空間和時間效率(XML已經被排除在外,因爲選項給出這個要求)

選項至今認爲:

任何建議或指針非常感謝。此外,如果您認爲上述任何信息不真實,請提供指示/示例來證明我錯了。

+0

HDF5確實有一些.NET支持:http://www.hdfgroup.org/projects/hdf.net/ – 2010-03-29 20:47:14

+0

@Richard Morgan Upto現在我只在hdfgroup.org上發現了關於.NET的死鏈接,謝謝。 – 2010-03-29 20:57:16

+0

看着用hdf.net提供的例子,它的想法是.net使用不安全和自定義編組,沒有樂趣。 – 2010-03-29 21:48:12

回答

6

您是否考慮過使用SQL Server Compact Edition

  1. 它有足夠的.NET支持
  2. 架構的版本,併爲您的應用處理舊模式將完全在你的控制的新版本的能力。使用舊版本中不存在的較新版本中的功能,SQL Server Compact的版本控制應該有點不可思議。
  3. 您可以使用可用於查詢的大多數SQL語法。
  4. 很顯然,從這個名稱來看,這個版本的SQL Server專爲嵌入式系統而設計,它可以包含那些希望避免安裝SQL Express或SQL Server完整版本的應用程序。

現在,這會和SQLite有相同的問題,因爲從您告訴我們的數據結構可能會變得複雜,但即使您使用自己的二進制格式,這也是正確的。

順便說一句,它發生在我身上,你還沒有明確什麼是「大」的意思。如果「大小」意味着接近或超過4 GB,顯然SQL Compact將無法工作,也不會有大量其他數據庫文件格式。

編輯我注意到你在我的文章後添加了SQL Compact Edition到你的「太重量級」列表中。根據數據庫的大小,SQL Compact只需要5MB的RAM和2MB的磁盤存儲空間。所以,問題不可能是重量級的。現在,關於聲稱數據結構的第二點會非常複雜。如果這是真的,我懷疑任何關係數據庫產品都是如此,並且滾動你自己的二進制格式將變得更加複雜。鑑於此,您可以查看非關係數據庫產品,如mongodb

+1

我認爲SQL CE或SQLite是最好的方法。很難提出不瞭解當前數據結構的建議,但嵌入式數據庫肯定提供了所有要求。您還可以獲得允許您直接在文件中查詢表格/數據的工具(便於調試/測試)。 – 2010-04-07 01:23:21

+0

我在這上面。如果你想高效的隨機訪問持久數據,那麼你需要一個數據庫,可能是關係數據庫或kvp數據庫。這正是數據庫*用於*的原因。這是事實上的標準,似乎滿足所有4個要求 - 而SQL CE/SQLite遠不是「重量級」。 – Aaronaught 2010-04-07 01:42:39

1

你會考慮(B)JSON嗎?如果是這樣,一個面向文檔的數據庫可能適合您的需求。 CouchDB是帶有REST API的JSON文檔存儲(絕對可用於.Net)。 CouchDB文檔可以具有二進制附件,我已經與在文檔中存儲多MB附件的人討論過,沒有問題。我相信MongoDB是一種使用二進制JSON作爲存儲格式的替代文檔數據庫,它也具有.Net綁定。

這些「NoSQL」選項很容易進行版本化,因爲它們本質上是無模式的。 JSON相當緊湊,他們肯定允許更新現有數據。

+0

請注意,BSON被列爲丟棄選項之一,此外我不希望存儲二進制blob,但.net數據結構可能相當大,但由許多部分組成。 – 2010-04-06 22:18:02

+0

BJSON是磁盤格式的實現細節。爲了這個用途,它非常有效。您當然可以輕鬆地擴展或更新MongoDB中的文檔,否定您對第3條的排除。您可以將數據結構序列化爲可以查詢的MongoDB文檔等。磁盤存儲上的任何文件都是磁盤上的二進制BLOB。這個或任何存儲方案都是一種邏輯抽象,可以更輕鬆地處理磁盤存儲。我認爲你會發現比文檔數據庫更好的東西。 – 2010-04-07 03:49:35

+0

我認爲像mongo這樣的基於文檔的nosql數據庫可以滿足要求,如果需要的話,您可以獲得可擴展性選項作爲獎勵。 – Brimstedt 2010-04-07 19:16:39

0

你看過二進制序列化了嗎?

查看我的帖子here瞭解更多信息。它有示例代碼來序列化包含在Dictionary對象中的自定義類。不知道你的結構有多複雜,但它應該是非常直接的,以適應你的需求。

添加評論,如果你需要更多的幫助......

+0

看到我最新的編輯我知道二進制/ xml序列化,但兩個選項都被拒絕。 – 2010-04-06 22:08:39

+0

好吧,但二進制序列化!= xml序列化。我仍然會檢查出來。 – GalacticJello 2010-04-07 19:09:04

0

如果XML不符合由於空間的消費需求,你可以通過System.IO.Compression.DeflateStream喂XML以減小其大小。 Deflate算法與GZip壓縮算法基本相同,但速度可高達40%(請參閱Jeff Atwood's blog)。

+0

XML不可搜索(無索引),也無法搜索壓縮的流/文件。 – 2010-04-07 09:52:58

0

我不會很快地註銷Protocol Buffers。當然,你所引用的手動輸入是指一兆字節的順序,而你正在處理幾十兆字節...但是你是否嘗試了一項研究來查看這個限制是否會影響到你?

如果它仍然影響你,我的建議是採用混合方法:將數據集切片並切成1 MB大小的塊,然後將每個塊存儲爲SQLite表的字段(作爲二進制blob )。將其他字段添加到您要索引的元素(或通過搜索)的表格中。

是的,它增加了複雜性,但沒有其他東西似乎讓你接近你需要去的地方。

1

你認爲像db4o這樣的東西?許可可能會限制你,但它似乎適合該法案,否則。

1

這裏是想一個有趣的選擇:來自思科,在Apache許可使用蝕刻(你支付任何版稅和軟件仍然是商業和你的。)

的想法是利用蝕刻的組件之間的通信您系統,以二進制形式。該格式對版本變化具有適應性,並且可以處理缺少的字段等',因爲您的要求狀態。

好處是您可以在二進制格式的基礎上獲得更完整的傳輸系統。它被認爲非常快(一臺機器每秒執行900次SOAP XML事務,發生了5萬次ETCH事務)。

如果您需要多個索引,則可以將二進制表單存儲在輕量級RDBMS中。如果只有一個索引就足夠了,那麼一個簡單的鍵/值存儲(CouchDB/MongoDB,甚至分佈式環境的Cassandra)也會爲您提供出色的存儲性能!