Синхронизация базы данных 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 минут, копии всех строк журнала из базы данных в памяти во внешнюю базу данных (и удаляет их из базы данных в памяти). Когда ваша программа будет готова к завершению, разбудите фоновый поток в последний раз, чтобы сохранить последние журналы, а затем закройте все соединения.