Синхронизация базы данных sqlite из памяти в файл - PullRequest
8 голосов
/ 22 июня 2010

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

Выполнение моих запросов при использовании файловой базы данных занимает много времени и делаетотставание в работе компьютера.

Необязательным решением является использование базы данных в памяти (она будет уместна, не беспокойтесь) и время от времени синхронизируйте ее с диском,

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

Можно ли решить эту проблему с помощью Qt 'SQL wrapper?

Ответы [ 3 ]

11 голосов
/ 28 июня 2010

Предположим, у вас есть база данных на диске с именем disk_logs и таблица с именем events.Вы можете присоединить базу данных в памяти к существующей базе данных:

ATTACH DATABASE ':memory:' AS mem_logs;

Создать таблицу в этой базе данных (которая будет полностью в памяти) для получения входящих событий журнала:

CREATE TABLE mem_logs.events(a, b, c);

Затем перенесите данные из таблицы в памяти в таблицу на диске во время простоя приложения:

INSERT INTO disk_logs.events SELECT * FROM mem_logs.events;

И затем удалите содержимое существующей таблицы в памяти.Повторите.

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

Прежде чем пытаться что-то ( неудобно перегружено ), как это, я бы также предложил попытаться сделать SQLite максимально быстрым .SQLite должен легко обрабатывать записи> 50K в секунду.Несколько записей журнала дважды в секунду не должны вызывать существенного замедления.

5 голосов
/ 28 июня 2010

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

  • Подсчитать количество вставленных записей
  • Начать транзакцию
  • Вставьте свою запись
  • Количество приращений
  • Подтверждение / завершение транзакции, когда N записей было вставлено
  • Повторите

Недостатком является то, что в случае сбоя системы в течение этого периода вы рискуете потерять незафиксированные записи (но если вы захотите использовать базу данных в памяти, то, похоже, вы согласны с этим риском). 1017 *

2 голосов
/ 22 июня 2010

Краткий поиск документации по SQLite не дал ничего полезного (маловероятно, и я этого не ожидал).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...