Sqlite3 / C ++ выполняет инструкцию DELETE без изменения размера БД - PullRequest
1 голос
/ 10 февраля 2012

Как это возможно?У меня есть простое приложение C ++, которое использует SQLite3 для вставки / удаления записей.Я использую одну базу данных и одну таблицу внутри.Затем после того, как я решил сохранить некоторые данные в БД, это происходит, и размер my.db естественным образом увеличивается.

Хотя есть проблема с DELETE - это не так.Но если я сделаю:

sqlite3 my.db
sqlite> select count(*) from mytable;

, вернется 0, что нормально, но если сделать ls -l в папке, содержащей my.db, размер будет таким же.

Может кто-нибудьобъяснить?

Ответы [ 2 ]

4 голосов
/ 10 февраля 2012

Когда вы выполняете запрос DELETE, Sqlite фактически не удаляет записи и не переставляет данные. Это займет слишком много времени. Вместо этого он просто помечает удаленные записи и игнорирует их с тех пор.

Если вы действительно хотите уменьшить размер данных, выполните команду VACUUM. Существует также возможность автоматической уборки пылесосом. Смотри http://www.sqlite.org/lang_vacuum.html.

4 голосов
/ 10 февраля 2012

Сценарий указан в Часто задаваемых вопросах SQLite :

(12) Я удалил много данных, но файл базы данных не стал меньше,Это ошибка?

Нет.Когда вы удаляете информацию из базы данных SQLite, неиспользуемое дисковое пространство добавляется во внутренний «свободный список» и используется повторно при следующей вставке данных.Дисковое пространство не потеряно.Но он также не возвращается в операционную систему.

Если вы удалили много данных и хотите сжать файл базы данных, выполните команду VACUUM.VACUUM восстановит базу данных с нуля.Это оставит базу данных с пустым свободным списком и файлом минимального размера.Однако обратите внимание, что запуск VACUUM может занять некоторое время (около полсекунды на мегабайт в системе Linux, где разрабатывается SQLite), и он может использовать вдвое больше временного дискового пространства, чем исходный файл, пока онвыполняется.

Начиная с SQLite версии 3.1, альтернативой использованию команды VACUUM является режим автоматического вакуума, включаемый с помощью прагмы auto_vacuum .

. Документация вашего друга; пожалуйста используйте его.


Также с документация :

Когда информация удаляется в базе данных,и страница btree становится пустой, она не удаляется из файла базы данных, а вместо этого помечается как «свободная» для будущего использования.Когда потребуется новая страница, SQLite будет использовать одну из этих бесплатных страниц перед увеличением размера базы данных.Это приводит к фрагментации базы данных, когда размер файла увеличивается сверх размера, необходимого для хранения его данных, и сами данные становятся беспорядочными в файле.

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

Самый простой способ удалить пустые страницы - использовать команду SQLite VACUUM.Это можно сделать с помощью вызовов библиотеки SQLite или утилиты sqlite.

Ниже приведены подробные примеры.

...