Intereting Posts

Лучшая практика хранения данных в памяти и базе данных одновременно на Android

Мы разрабатываем приложение для Android, в котором много данных («клиенты», «продукты», «заказы» …), и мы не хотим запрашивать SQLite каждый раз, когда нам нужна какая-то запись. Мы хотим избежать запросов к базе данных как можно больше, поэтому мы решили хранить определенные данные всегда в памяти.

Наша первоначальная идея – создать два простых класса:

  1. «MemoryRecord»: класс, который будет содержать в основном массив объектов (строка, int, double, datetime и т. Д.), Которые являются данными из записи таблицы, и все методы для получения этих данных из этого массив.

  2. «MemoryTable»: класс, который будет содержать в основном карту [Key, MemoryRecord] и все методы для управления этой Картой и вставки / обновления / удаления записи в / из базы данных.

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

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

Но нам нужна помощь / совет от вас. Можете ли вы предложить что-то более простое или эффективное для реализации такой вещи? Или, может быть, некоторые существующие классы, которые уже делают это для нас?

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

Но, допустим, у нас есть таблица с 2000 записями, и мне нужно будет перечислить эти записи. Для каждого из них я должен запросить другие 30 таблиц (некоторые из них с 1000 записями, другие с 10 записями), чтобы добавить дополнительную информацию в список, и это пока «летает» (и, как вы знаете, мы должны быть очень быстрыми в данный момент).

Теперь вы скажете: «Просто создайте свой основной запрос со всеми этими« объединениями »и принесите все необходимое за один шаг. SQLite может быть очень быстрым, если ваша база данных хорошо разработана и т. Д.».

ОК, но этот запрос станет очень сложным и уверенным, хотя SQLite очень быстро, он будет «слишком» медленным (2 раза в 4 секунды, как я уже подтвердил, и это не приемлемое для нас время).

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

Таким образом, альтернатива приводит только к основным записям (это никогда не изменится, независимо от того, что пользователь делает или хочет) без соединения (это очень быстро!) И запрашивать другие таблицы каждый раз, когда нам нужны некоторые данные. Обратите внимание, что в таблице с 10 записями мы будем извлекать одни и те же записи много и много раз. В этом случае это пустая трата времени, потому что, несмотря на быстрый SQLite, всегда будет дороже запрос, курсор, выборка и т. Д., А не просто захват записи из своего «кэша памяти». Я хочу пояснить, что мы не планируем постоянно хранить все данные в памяти, а только некоторые таблицы, которые мы запрашиваем очень часто.

И мы подошли к первому вопросу: что является лучшим способом «кэшировать» эти записи? Мне очень нравится сосредоточиться на этом обсуждении, а не «зачем вам кешировать данные?»

Solutions Collecting From Web of "Лучшая практика хранения данных в памяти и базе данных одновременно на Android"

Подавляющее большинство приложений на платформе (контакты, электронная почта, Gmail, календарь и т. Д.) Этого не делают. Некоторые из них имеют чрезвычайно сложные схемы базы данных с потенциально большим объемом данных и не нужно это делать. То, что вы предлагаете сделать, будет причинять вам огромную боль без ясного выигрыша.

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

  • У вас действительно сложные схемы данных.
  • У вас очень большой объем данных.

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

Фактически оптимизация схемы может быть немного черным искусством (и я не эксперт в этом), но некоторые вещи, которые нужно искать, правильно создают индексы в строках, которые вы запрашиваете, разрабатываете объединения, чтобы они могли эффективно использовать пути и т. Д. Я уверен, что есть много людей, которые могут помочь вам в этой области.

Вы также можете попытаться взглянуть на источник некоторых баз данных платформы, чтобы получить представление о том, как проектировать для хорошей производительности. Например, база данных контактов (особенно начиная с версии 2.0) чрезвычайно сложна и имеет множество оптимизаций для обеспечения хорошей производительности на относительно больших данных и расширяемых наборах данных с большим количеством различных запросов.

Обновить:

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

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

Какова была эта оптимизация?

Это было создание временного индекса в точке обновления в важном столбце, используемом в операциях обновления. (И затем удалите его, когда закончите.) Таким образом, это 60-кратное повышение производительности происходит даже при том, что оно также включает время, необходимое для создания индекса на одном из столбцов, используемых во время обновления.

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

Проблема с кешем памяти, конечно, заключается в том, что вам нужно синхронизировать ее с базой данных. Я обнаружил, что запрос к базе данных на самом деле довольно быстрый, и вы можете быть предварительно оптимизированы здесь. Я провел много тестов по запросам с разными наборами данных, и они никогда не занимают больше 10-20 мс.

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

Если вы собираетесь хранить кеш памяти, вы можете захотеть, чтобы база данных уведомила кеш при его изменении содержимого, а затем вы можете обновить кеш. Таким образом, любой может обновить базу данных, не зная о кешировании. Кроме того, если вы создаете ContentProvider над своей базой данных, вы можете использовать ContentResolver для уведомления об изменениях, если вы зарегистрируетесь с помощью registerContentObserver.