Синхронизация базы данных SQLite из памяти в файл

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

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

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

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

могу ли я решить эту проблему с помощью Qt ' s SQL фантик?

3 ответов


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

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 запись вставки в секунду. Несколько записей журнала дважды в секунду не должны вызывать значительного замедления.


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

  • подсчитайте количество записей, вставленных до сих пор
  • начать транзакцию
  • вставить запись
  • приращение
  • Commit / end транзакция, когда n записей были вставлены
  • повторить

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


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

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