2008-09-26 3 views
4

У меня есть идея, как решить эту проблему, но я хотел знать, есть ли что-то более легкое и более расширяемое для моей проблемы.Лучший (бесплатный) способ хранения данных? Как насчет обновлений файловой системы?

Программа, в которой я работаю, имеет две основные формы данных: изображения и информацию, связанную с этими изображениями. Информация, связанная с изображениями, ранее была сохранена в базе данных JET с предельной простотой (четыре таблицы), которая оказалась медленной и неполной в сохраненных полях. Мы переходим к новой реализации хранения данных. Учитывая простоту задействованных структур данных, я думал, что база данных переполнена.

Каждое изображение будет иметь информацию о его собственных (параметры захвата), будет частью группы изображений, которые взаимосвязаны (взяты за тот же тридцатиминутный период, скажем), а затем часть большей группы (взято того же лица). Сейчас я храню людей в словаре с уникальным идентификатором. Затем у каждого человека есть список различных групп изображений, и каждая группа изображений имеет список изображений. Все эти классы являются сериализуемыми, и я просто сериализую и десериализую словарь. Довольно простой материал. Изображения хранятся отдельно, так что словарь не становится астрономическим по размеру.

Проблема в том, что происходит, когда мне нужно добавить новые информационные поля? Есть ли простой способ настроить эти структуры данных для учета возможных будущих изменений? В прошлом способ, которым я бы справился с этим на C, заключался в создании сериализуемой структуры с большим количеством пустых байтов (по крайней мере, k) для будущей расширяемости с одним из байтов в структуре, указывающей версию. Затем, когда программа прочитает структуру, она будет знать, какую десериализацию использовать на основе массивного оператора switch (а старые версии могут читать новые данные, поскольку посторонние данные просто попадают в поля, которые игнорируются).

Существует ли такая схема в C#? Например, если у меня есть класс, который представляет собой группу объектов String и Int, а затем я добавляю в Structor объект String, как я могу десериализовать объект с диска, а затем добавить строку к нему? Нужно ли мне смириться с несколькими версиями классов данных и фабрикой, которая принимает поток десериализации и обрабатывает десериализацию на основе некоторой информации о версии, хранящейся в базовом классе? Или такой класс, как словарь, идеально подходящий для хранения такого рода информации, поскольку он автоматически десериализует все поля на диске, и если в него будут добавлены новые поля, я могу просто перехватить исключения и заменить их на пустые строки и интс для этих значений?

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

Спасибо!

ответ

1

Мой мозг жарен в данный момент, поэтому я не уверен, что могу посоветовать за или против базы данных, но если вы ищете сериализацию с обновлением версии, вы будете дураком, чтобы хотя бы проверить в Protocol Buffers. .

Вот краткий список реализаций я знаю о для C#/NET:

+0

К сожалению, это C#, поэтому протокольные буферы недоступны для этого языка (пока!) – mmr 2008-09-26 22:16:33

2

Sqlite - это то, что вы хотите. Это быстрая, встраиваемая однофайловая база данных, которая имеет привязки к большинству языков.

Что касается расширяемости, вы можете хранить свои модели с атрибутами по умолчанию, а затем иметь отдельную таблицу для расширений атрибутов для будущих изменений.

Через год или два по дороге, если код все еще используется, вы будете счастливы, что 1) другим разработчикам не нужно будет изучать настроенную структуру кода для поддержки кода, 2) вы можете экспортировать , просматривать, изменять данные с помощью стандартных инструментов базы данных (есть драйвер ODBC для файлов sqlite и различных инструментов запросов), и 3) вы сможете масштабировать до базы данных с минимальными изменениями кода.

+0

Итак, отдельная таблица для каждой из других таблиц? Будут ли я затем загружать их в объекты класса, поэтому они должны поддерживать как объекты, так и таблицы данных? Как мне обновить таблицы? Много деталей с этими реализациями базы данных я не понимаю ... – mmr 2008-09-26 21:53:17

1

Существует схема базы данных, для которой я не могу вспомнить имя, которое может справиться с такой ситуацией. У вас в основном есть две таблицы.Одна таблица хранит имя переменной, а другая сохраняет значение переменной. Если вы хотите сгруппировать переменные, добавьте третью таблицу, которая будет иметь отношение от одного до многих с таблицей имен переменных. Преимущество этой настройки заключается в том, что вы можете добавлять разные переменные, не изменяя схему базы данных. Несколько раз сохранял мой бекон, когда занимался отделами, которые часто меняют свое мнение (например, маркетинг).

Единственный недостаток заключается в том, что для таблицы значений переменных необходимо сохранить фактическое значение в виде столбца строки (фактически varchar или nvarchar). Затем вам приходится иметь дело с хлопотами о преобразовании значений обратно в их собственные представления. В настоящее время я поддерживаю что-то вроде этого. Таблица переменных в настоящее время насчитывает около 800 миллионов строк. Это все еще довольно быстро, так как я могу получить некоторые вариации значений за одну секунду.

+0

Это называется моделью EAV (Entity/Attribute/Value). Он популярен в таких областях, как фармацевтическое тестирование, где у них нет хорошей справки о возможных столбцах. – Turnkey 2008-09-26 22:22:21

+0

Интересно. Итак, у меня будет несколько таблиц (возможно, в sqlite, я собираюсь), а затем поддерживаю кучу классов, в которые создаются данные, а затем используйте словарь в качестве встроенной памяти, не так ли? – mmr 2008-09-26 22:22:54

1

Я не C# программист, но мне нравится mmap() и увидел, что есть проект, делающий такую ​​вещь для C#.

См Mmap

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

  • Управление до 4 гигабайт информации.
  • Пространство можно оптимизировать для реального размера данных.
  • Все данные могут быть просмотрены как один массив и доступны с операциями чтения/записи.
  • Не нужно структурировать, чтобы хранить, а просто использовать и хранить.
  • Может быть кэширован. Очень многоразовый.
0

Так идут с sqllite по следующим причинам:
1. Вам не нужно читать/писать всю базу данных с диска каждый раз, когда
2. Намного проще добавить, даже если вы не «т оставить достаточно заполнителей в начале
3. легче поиск на основе все, что вы хотите
4. легче изменить данные таким образом, за приложение было разработано

Проблемы с Dictionary подхода
1.Если вы не сделали смарт-словарь, вам нужно каждый раз читать/писать всю базу данных (если вы не тщательно разработаете структуру данных, будет очень сложно поддерживать обратную совместимость)
----- а) если вы не оставили достаточно держатели мест bye bye
2. Похоже, что вам нужно было бы выполнить линейный поиск по всем фотографиям для поиска по одному из атрибутов захвата
3. Можно ли сделать картинку более чем в одной группе? Может ли картина находиться под более чем одним человеком? Могут ли два человека быть в одной группе? Со словарями эти вещи могут стать волосатыми ....

С таблицей базы данных, если вы получаете новый атрибут, вы можете просто сказать: «Добавить таблицу изображений» Добавить атрибут DataType. Затем, пока вы не делаете правило, указывающее, что атрибут должен иметь значение, вы можете загружать и сохранять более старые версии. В то же время новые версии могут использовать новые атрибуты.

Также вам не нужно сохранять изображение в базе данных. Вы можете просто сохранить путь к изображению в базе данных. Затем, когда приложение нуждается в изображении, просто загрузите его из файла диска. Это уменьшает размер базы данных. Кроме того, дополнительное время поиска для получения файла диска, скорее всего, будет незначительным по сравнению с временем загрузки изображения.

Возможно, ваша таблица должна быть
Picture (PictureID, GroupID ?, Путь к файлу, захват Параметр 1, захват Параметр 2, и т.д ..)

Если вы хотите больше гибкости вы могли бы сделать таблицу CaptureParameter (PictureID, ParameterName, ParameterValue) ... Я бы посоветовал это сделать, потому что он намного менее эффективен, чем просто помещать их в одну таблицу (не говоря уже о том, что запросы для извлечения/поиска параметров захвата будут более сложными).

Person (PersonID, Любое лицо, атрибуты, как имя/Etc.)
Group (GroupID, имя группы, PersonID?)
PersonGroup? (PersonID, GroupID)
PictureGroup? (GroupID, PictureID)

2

Просто небольшое предупреждение, SQLLite, протокольные буферы, mmap и др. ... все очень хорошо, но вы должны прототипировать и протестировать каждую реализацию и убедиться, что вы не столкнетесь с теми же проблемами с перфорацией или различными узкими местами.

Простота может быть просто повышена до SQL (Express) (вы можете быть удивлены первичным усилением) и исправить все, что отсутствует в настоящем дизайне базы данных. Тогда, если перфорация все еще остается проблемой, исследуйте эти другие технологии.

Смежные вопросы