Версионный, расширяемый двоичный формат файла - PullRequest
12 голосов
/ 30 марта 2010

В проекте, над которым я сейчас работаю, необходимо сохранить значительную структуру данных на диск (редактирование: подумайте о десятках МБ). Будучи оптимистом, я думал, что должно быть стандартное решение для такой проблемы; однако до сих пор я не нашел решения, которое удовлетворяет следующим требованиям:

  1. .NET 2.0 поддержка, желательно с реализацией FOSS
  2. Версия дружественная (это следует интерпретировать как: чтение старой версии формата должно быть относительно простым, если изменения в базовой структуре данных просты, скажем, добавление / удаление полей)
  3. Возможность сделать некоторую форму произвольного доступа, когда часть данных может быть расширена после первоначального создания, без необходимости десериализации коллекции, созданной до этого момента времени (представьте, что это расширение промежуточных результатов)
  4. Эффективное использование пространства и времени (XML был исключен как опция с учетом этого требования)

Варианты, рассмотренные до сих пор:

  • XmlSerializer : было отказано, поскольку сериализация xml не удовлетворяет требованиям 3 и 4.
  • SerializableAttribute : не поддерживает требования 2 и 3.
  • Буферы протокола : был отклонен по вердикту документации о Больших наборах данных - так как в этом комментарии предлагалось добавить еще один слой сверху, это потребовало бы дополнительной сложности, которую я желаю обрабатываться самим форматом файла.
  • HDF5 , EXI : похоже, нет реализации .net
  • SQLite / SQL Server Compact edition : имеющаяся структура данных может привести к довольно сложной структуре таблицы, которая кажется слишком тяжелой для предполагаемого использования
  • BSON : не соответствует требованию 3.
  • Fast Infoset : кажется, только платные реализации .NET.

Любые рекомендации или указатели с благодарностью. Кроме того, если вы считаете, что какая-либо из приведенных выше сведений не соответствует действительности, предоставьте указатели / примеры, чтобы доказать, что я неправ.

Ответы [ 7 ]

6 голосов
/ 02 апреля 2010

Рассматривали ли вы использование SQL Server Compact Edition ?

  1. Имеет много поддержки .NET
  2. Управление версиями схемы и возможность для новых версий вашего приложения обрабатывать старые схемы будут полностью под вашим контролем. Управление версиями SQL Server Compact должно казаться чем-то вроде вашего приложения, использующего функции в более новой версии, которых не было в более старой версии.
  3. У вас есть большая часть синтаксиса SQL, доступного вам для запросов.
  4. Как видно из названия, эта версия SQL Server была разработана для встроенных систем, которые могут включать в себя приложения, которые хотят избежать установки SQL Express или полной версии SQL Server.

Теперь, это будет иметь те же проблемы, что и SQLite, в том, что структура данных, из того, что вы сказали нам, может быть сложной, но это будет так, даже если вы используете собственный двоичный формат.

Кстати, мне приходит в голову, что вы не пояснили, что именно подразумевается под "значительным". Если «sizeable» означает около 4 ГБ или более, очевидно, что SQL Compact не будет работать, как и множество других форматов файлов базы данных.

РЕДАКТИРОВАТЬ Я заметил, что вы добавили SQL Compact Edition в свой список "слишком тяжеловесных" после моего поста. Для SQL Compact требуется только 5 МБ ОЗУ и 2 МБ дискового пространства в зависимости от размера базы данных. Итак, проблема не в том, что это тяжеловес. Теперь, что касается второго пункта утверждения структуры данных, это будет довольно сложно. Если это так, я подозреваю, что это будет верно для любого продукта реляционной базы данных, и переход на ваш собственный двоичный формат будет еще более сложным. Учитывая это, вы можете посмотреть на нереляционные продукты баз данных, такие как mongodb .

1 голос
/ 08 апреля 2010

Вот интересный вариант: ETCH от Cisco, доступный по лицензии Apache (вы не платите лицензионные платежи, а ваше программное обеспечение остается коммерческим и вашим.)

Идея заключается в использовании Etch для связи между компонентами вашей системы в двоичном виде. Формат устойчив к изменениям версии и может обрабатывать пропущенные поля и т. Д. В соответствии с вашими требованиями.

Преимущество заключается в том, что вы получаете более полную систему передачи поверх двоичного формата. Это считается очень быстрым (машина, выполняющая 900 XML-транзакций SOAP в секунду, выполняет 50 000 транзакций ETCH).

Вы можете хранить бинарную форму в облегченной РСУБД, если вам нужно несколько индексов. Если бы достаточно было только одного индекса, то простое хранилище ключей / значений (CouchDB / MongoDB или даже Cassandra для распределенных сред) также дало бы вам прекрасную производительность хранения!

1 голос
/ 07 апреля 2010

Рассматривали ли вы что-то вроде db4o ? Лицензирование может ограничить вас, но, в противном случае, это будет соответствовать требованиям.

1 голос
/ 03 апреля 2010

Считаете ли вы (B) JSON? Если это так, одна из документов-ориентированных баз данных может соответствовать вашим потребностям CouchDB - это хранилище документов JSON с REST API (определенно можно использовать из .Net). Документы CouchDB могут иметь двоичные вложения, и я общался с людьми, которые хранили вложения размером в несколько МБ в документах без проблем. Я считаю, что MongoDB , альтернативная база данных документов, использующая двоичный JSON в качестве формата хранения, также имеет привязки .Net.

Эти альтернативы "NoSQL" легко версии, потому что они по существу без схемы. JSON довольно компактен, и они, безусловно, позволяют обновлять существующие данные.

0 голосов
/ 07 апреля 2010

Я бы не стал так быстро списывать протоколные буферы. Конечно, ссылка, которую вы указываете вручную, говорит о порядке мегабайта, а вы имеете дело с десятками мегабайт ... но вы пробовали провести исследование, чтобы выяснить, влияет ли это ограничение на вас?

Если это все еще влияет на вас, я предлагаю использовать гибридный подход: нарезать и разрезать набор данных на куски размером 1 МБ, а затем сохранить каждый кусок как поле таблицы SQLite (как двоичный двоичный объект) , Добавьте в таблицу другие поля для элементов, по которым вы хотите проиндексировать (или выполнить поиск).

Да, это добавляет сложности, но, похоже, больше ничего не приближает вас к тому месту, куда вам нужно идти.

0 голосов
/ 07 апреля 2010

Если XML не соответствует требованиям из-за потребления места, вы можете передать XML через System.IO.Compression.DeflateStream, чтобы уменьшить его размер.Алгоритм Deflate по сути аналогичен сжатию GZip, но может быть на 40% быстрее (см. блог Джеффа Этвуда ).

0 голосов
/ 06 апреля 2010

Вы смотрели на двоичную сериализацию?

Смотрите мой пост здесь для получения дополнительной информации. Он имеет пример кода для сериализации пользовательского класса, содержащегося в объекте Dictionary. Не знаю, насколько сложна ваша структура, но адаптировать ее к вашим потребностям должно быть довольно просто.

Добавьте комментарий, если вам нужна дополнительная помощь ...

...