Лучший (бесплатный) способ хранения данных?Как насчет обновлений файловой системы?

StackOverflow https://stackoverflow.com/questions/142114

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

Спасибо!

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

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

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

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

Видишь Mmap

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

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

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

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

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

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

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

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

Person (PersonID, Любые атрибуты Person, такие как Name / И т.д.)
Группа (groupId, Название группы, PersonID?)
PersonGroup?(PersonID, groupId)
Фотогруппа?(groupId, PictureID)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top