Практичный способ хранения «достаточно большого» объема данных, который почти никогда не изменяется?

13

Думайте с точки зрения предварительно вычисленных таблиц поиска или чего-то еще. В какой момент имеет смысл использовать базу данных вместо значений жесткого кода в моем приложении? Значения не собираются меняться, и они приятно отделены от разработчиков обслуживания. 100 значений, 1К, 10К, 100К? Я хочу хранить около 40 тыс. Значений. Прямо сейчас это сгенерированный машиной switchоператор (о котором VS2010 недоволен).

редактировать:

Если кому-то интересно, вот как я подошел к этому: мои данные можно было хранить в двух массивах с плавающей запятой по 100 тыс. Элементов, поэтому я так и сделал. Генерация данных заняла около 20 секунд, поэтому я сделал это один раз и сериализовал их во встроенный ресурс с помощью BinaryFormatter. Распаковка данных занимает около 5 миллисекунд при запуске приложения и превосходит реализацию базы данных, которую я заменял (эти жестко заданные значения были сохранены ранее), почти в 45 000 раз.

Брайан Бетчер
источник

Ответы:

5

Мое предложение состоит в том, чтобы сохранить данные в файл или таблицу базы данных. Если скорость не является проблемой, тогда запросите файл или базу данных (база данных лучше) во время выполнения. Если с памятью нет проблем, но вам нужна скорость, загрузите данные в память при запуске программы. В C # вы можете использовать и массив, список или (лучший вариант) хеш-таблицу и иметь метод для возврата данных, которые вам нужны во время выполнения (например, getDataValue (string keyToValue)).

Я бы порекомендовал вам не использовать оператор switch, так как его было бы очень сложно поддерживать и это привело бы к большой занимаемой памяти.

Хеш-таблица, например, http://support.microsoft.com/kb/309357

Адам Ф
источник
В конечном итоге это то, что я сделал: проверьте мой обновленный пост.
Брайан Бетчер
1
+1 за предложение базы данных. Базы данных созданы для хранения больших объемов данных и позволяют вам извлекать их очень быстро.
NoChance
См. Stackoverflow.com/questions/301371/… о том, почему для этого лучше использовать словарь, а не хеш-таблицу. YMMV
Крис Макки
6

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

Однако хранение и доступ к данным с помощью оператора C # switch является довольно плохой практикой, поскольку в тесной связи между хранилищем данных и моделью доступа к данным подразумевается только один метод доступа к методу (по параметру switch).

Я бы предпочел хранить данные в Hashtable или Dictionary, а также предоставлять отдельные классы для извлечения данных и одноразовое заполнение справочных словарей.

Недавно я обнаружил, что довольно удобно реализовывать небольшой DSL для определения бизнес-правил ( свободный интерфейс для SiteMap или метод проверки вопросов на собеседовании в налоговом калькуляторе «calc» для определения правил), а затем предоставить отдельный объект для запроса этих правил. Этот метод хорошо подходит для сценария переключения.

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

Валера Колупаев
источник
Я расширил ответ несколькими примерами.
Валера Колупаев
2

Заявление о переключении линии 40 КБ немного сомнительно. Я предполагаю, что вам все еще нужно выполнять операции с запросами, верно? Вы пытались инкапсулировать данные? Затем используйте LINQ для выполнения операций запроса в коллекции для проверки производительности. Получить некоторые конкретные разы запустив модульные тесты с помощью таймера , как StopWatch . Тогда, если вы думаете, что это может просто сработать. Посмотрите, является ли производительность приемлемой для пользователей.

P.Brian.Mackey
источник
2

У меня было такое требование дважды. Приложения были разработаны, чтобы быть автономными без установки базы данных / доступа не требуется. В обоих случаях я использовал XML-файлы для хранения данных. В первом, который был на 2.0 Framework, я использовал вызовы парсинга XML старого стиля для поиска данных. Для более новой версии 3.5 Framework я использовал LINQ to XML, чтобы найти то, что мне нужно. В обоих случаях доступ к данным был заключен в классы.

jfrankcarr
источник
1

Главное здесь - убедиться, что ваш общедоступный интерфейс инкапсулирует вашу реализацию, но это не ваш вопрос, и нет причин думать, что вы этого не сделали. Кроме того, это просто вопрос производительности против скорби (и различия в производительности вполне могут не стоить того, чтобы о них заботиться). В качестве практического решения для проблемы VS 2010 вы всегда можете разбить оператор case на иерархию операторов case - верхний уровень может вызвать один из 10 других методов, каждый из которых, например, с оператором case из 4000 case. Вы можете поместить каждый из 10 в свой файл, если нужно. Немного отвратительно, но вы все равно генерируете код.

Что касается числа для переключения на БД - это просто всякий раз, когда не использовать БД становится проблемой.

PSR
источник
Я ценю мысль о том, что мой интерфейс инкапсулирует реализацию: это, безусловно, делает. Функциональность раскрывается через GetValuesForInputметод -типа, и мое массивное утверждение скрыто в реализации.
Брайан Бетчер
1

Вы можете использовать что-то вроде SQL Compact. Положите данные в таблицу и оставьте файл БД в проекте. Таблицы лучше подходят для такого количества данных, чем оператор switch.

Морган Херлокер
источник
1

Я думаю, что ключевое слово здесь «вряд ли»

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

Если данные вряд ли когда-либо изменятся - например, коды телефонов, национальные границы и т. П. - я бы, вероятно, попытался каким-то образом сохранить данные извне. Особенно, если это начало становиться больше чем пара дюжин значений.

GrandmasterB
источник
1
Это зависит от того, насколько хорош компилятор. Оператор case в Delphi может быть чрезвычайно эффективным.
Лорен Печтел
1

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

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

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

Разделение данных и кода является хорошей практикой, особенно если данные большие.

Без шансов
источник