Файлы архивов SQLite
Оглавление
1. Введение
«Архив SQLite» — это контейнерный файл, подобный архиву ZIP или тар-архиву, но основанный на базе данных SQLite.
Архив SQLite — это обычный файл базы данных SQLite, который содержит следующую таблицу в своей схеме:
CREATE TABLE sqlar( name TEXT PRIMARY KEY, -- name of the file mode INT, -- access permissions mtime INT, -- last modification time sz INT, -- original file size data BLOB -- compressed content );
Каждая строка таблицы SQLAR содержит содержимое одного файла. Имя файла (полный путь относительно корня архива) находится в поле "name". Поле "mode" — это целое число, представляющее права доступа в стиле Unix для файла. "mtime" — это время изменения файла в секундах с 1970 года. "sz" — это исходный размер файла без сжатия. Поле "data" содержит содержимое файла. Содержимое обычно сжимается с помощью Deflate, хотя и не всегда. Если поле "sz" равно размеру поля "data", то содержимое хранится без сжатия.
1.1. База данных как контейнерный объект
Архив SQLite — это один из примеров более общей идеи, что база данных SQLite может вести себя как контейнерный объект, содержащий множество более мелких компонентов данных.
В клиентских/серверных базах данных, таких как PostgreSQL или Oracle, пользователи и разработчики, как правило, рассматривают базу данных как службу или «узел», а не как объект. Это связано с тем, что содержимое базы данных распределено по множеству файлов на сервере или, возможно, по нескольким серверам в кластере служб. Нельзя указать на один файл или даже одну директорию и сказать: «вот база данных».
SQLite, напротив, хранит всё содержимое в одном файле на диске. Этот единственный файл — то, на что можно указать и сказать: «вот база данных». Он ведет себя как объект. Файл базы данных SQLite можно копировать, переименовывать, отправлять как вложение в электронное письмо, передавать как аргумент запроса POST HTTP или иначе обрабатывать как другой объект данных, например, изображение, документ или медиафайл.
Исследования показывают, что многие приложения уже используют SQLite как контейнерный объект. Например, Кеннеди (не связан с разработчиком SQLite) сообщает, что 14% приложений Android никогда не записывали в свои базы данных SQLite. Предполагается, что эти приложения загружают целые базы данных из облака и затем используют информацию локально по мере необходимости. Другими словами, приложения используют SQLite не столько как базу данных, сколько как формат переносимого запроса.
1.2. Приложения, использующие архивы SQLite
Система распределенного контроля версий Fossil предоставляет пользователям возможность загружать коммиты как тар-архивы, архивы ZIP или архивы SQLite.
2. Преимущества архивов SQLite
Архив SQLite гибкий. Архивы ZIP и тар-архивы ограничены хранением только файлов. Архив SQLite хранит файлы плюс любые другие табличные и/или реляционные данные, которые, как кажется полезными для приложения.
Архив SQLite транзакционный. Обновления атомарны и долговечны, даже при сбоях или отключении питания в середине обновления. Читатели видят согласованную и неизменную версию содержимого, даже если другой процесс одновременно обновляет архив.
Архив SQLite можно обновлять по частям. Отдельные файлы можно добавлять, удалять или заменять, не переписывая весь архив.
-
Архив SQLite можно запросить с помощью языка запросов высокого уровня (SQL). Некоторые примеры:
- Какой общий размер всех файлов в архиве, имена которых оканчиваются на ".h" или ".cpp"?
- Какой процент файлов сжат менее чем на 25%?
- Сколько исполняемых файлов в архиве?
Приложения, которые уже используют SQLite для других целей, могут легко добавить поддержку архивов SQLite, используя небольшое расширение (https://sqlite.org/src/file/ext/misc/sqlar.c) для обработки сжатия и распаковки содержимого. Даже это крошечное расширение можно опустить, если файлы в архиве не сжаты. В отличие от этого, поддержка архивов ZIP и/или тар-архивов требует либо отдельных библиотек, либо большого количества дополнительного пользовательского кода, или иногда и того, и другого.
Архив SQLite может обойти цензуру, наложенную брандмауэром. Например, определённые типы файлов, считающиеся «опасными» (примеры: DLL), будут заблокированы Gmail и, вероятно, многими другими службами электронной почты и брандмауэрами, даже если файлы упакованы в архив ZIP или тар-архив. Но эти брандмауэры обычно ещё не знают об архивах SQLite, поэтому содержимое можно поместить в архив SQLite, чтобы избежать цензуры.
3. Недостатки архивов SQLite
Архив SQLite — относительно новый формат. Он был впервые описан в 2014 году. Архивы ZIP и тар-архивы существуют уже десятилетиями и прочно утвердились как стандартные форматы. Большинство программистов знают, что такое архив ZIP или тар-архив, но если вы скажете «архив SQLite», то с большей вероятностью получите ответ «Что это?» Инструменты для обработки архивов ZIP и тар-архивов с большей вероятностью будут установлены на стандартных компьютерах.
-
Поскольку база данных SQLite — это более общий формат (она разработана для гораздо большего, чем просто хранение набора файлов), она не такая компактная, как форматы архивов ZIP и тар-архивов. Архив SQLite обычно на 1% больше, чем эквивалентный архив ZIP. Тар-архивы сжимаются как единый блок, а не каждый файл отдельно, как это делается в архивах SQLite и ZIP. По этим причинам тар-архивы, как правило, меньше, чем архивы ZIP или SQLite.
Например, следующая таблица показывает относительные размеры архива SQLite, архива ZIP и тар-архива из 1743 файлов в дереве исходных кодов SQLite 3.22.0:
Архив SQLite 10 754 048 Архив ZIP (используя Info-ZIP 3.0) 10 662 365 Архив ZIP (используя zipfile) 10 390 215 Тар-архив 9 781 109 Архив SQLite поддерживает только метод сжатия Deflate. Архивы Tar и ZIP поддерживают более широкий набор методов сжатия.
4. Управление архивом SQLite из командной строки
Рекомендуемый способ создания, обновления, просмотра и извлечения архива SQLite — использовать оболочку командной строки sqlite3.exe для SQLite версии 3.23.0 (2018-04-02) или более поздней. Эта командная строка поддерживает параметр командной строки -A, который позволяет легко управлять архивами SQLite. Командная строка для SQLite версии 3.22.0 (2018-01-22) имеет команду .archive для управления архивами SQLite, но это требует взаимодействия с оболочкой.
Чтобы перечислить все файлы в архиве SQLite с именем "example.sqlar" с помощью одной из этих команд:
sqlite3 example.sqlar -At sqlite3 example.sqlar -Atv
Чтобы извлечь все файлы из архива SQLite с именем "example.sqlar":
sqlite3 example.sqlar -Ax
Чтобы создать новый архив SQLite с именем "alltxt.sqlar", содержащий все файлы *.txt в текущей директории:
sqlite3 alltxt.sqlar -Ac *.txt
Чтобы добавить или обновить файлы в существующем архиве SQLite:
sqlite3 example.sqlar -Au *.md
Для получения подсказок по использованию и краткого описания всех параметров просто передайте командной строке параметр -A без дополнительных аргументов:
sqlite3 -A
Все эти команды работают так же, если в качестве аргумента имени файла используется архив ZIP, а не база данных SQLite.
4.1. Другие утилиты командной строки
Так же, как существует программа "zip" для управления архивами ZIP и программа "tar" для управления тар-архивами, существует программа "sqlar" для управления архивами SQL. Программа "sqlar" может создавать новые архивы SQLite, просматривать содержимое существующего архива, добавлять или удалять файлы из архива и/или извлекать файлы из архива. Отдельная программа "sqlarfs" может смонтировать архив SQLite как систему файлов Fuse.
5. Управление архивами SQLite из кода приложения
Приложения могут легко читать или записывать архивы SQLite, подключаясь к SQLite и включив расширение ext/misc/sqlar.c для обработки сжатия и распаковки. Расширение sqlar.c создает две новые SQL-функции.
- sqlar_compress(X)
Функция sqlar_compress(X) пытается сжать копию двоичного объекта X с помощью алгоритма Deflate и возвращает результат в виде двоичного объекта. Если вход X не является сжимаемым двоичным объектом, возвращается копия X. Эта процедура используется при вставке содержимого в архив SQLite.
- sqlar_uncompress(Y,SZ)
Функция sqlar_uncompress(Y,SZ) отменяет сжатие, выполненное sqlar_compress(X). Параметр Y — сжатое содержимое (выход из предыдущего вызова sqlar_compress()), а SZ — исходный размер двоичного объекта X без сжатия, который сгенерировал Y. Если SZ меньше или равен размеру Y, это означает, что сжатие не выполнялось, и sqlar_uncompress(Y,SZ) возвращает копию Y. В противном случае sqlar_uncompress(Y,SZ) выполняет алгоритм Inflate для распаковки Y и восстановления его исходного состояния, возвращая несжатое содержимое. Эта процедура используется при извлечении содержимого из архива SQLite.
Используя эти две процедуры, приложения могут легко вставлять новые записи в или извлекать существующие записи из архива SQLite. Вставьте новую запись в архив SQLite, используя код подобный этому:
INSERT INTO sqlar(name,mode,mtime,sz,data)
VALUES ($name,$mode,strftime('%s',$mtime),
length($content),sqlar_compress($content));
Извлеките запись из архива SQLite, используя код подобный этому:
SELECT name, mode, datetime(mtime,'unixepoch'), sqlar_uncompress(data,sz) FROM sqlar WHERE ...;
Приведенный выше код предназначен для общего случая. В случае SQLite-архива, который хранит только не сжатые или несжимаемые данные (это может потребоваться, например, в SQLite-архиве, хранящем только изображения JPEG, GIF и/или PNG), данные можно вставлять в базу данных и извлекать из нее без использования функций sqlar_compress() и sqlar_uncompress(), а расширение sqlar.c не требуется.
Эта страница была обновлена 12 января 2023 г. в 11:08:35 UTC
SQLite is in the Public Domain.
https://sqlite.org/sqlar.html