SQLite 아카이브 파일
SQLite 아카이브 파일 (SQLite Archive Files)
소개 (Introduction)
"SQLite 아카이브"(SQLite Archive)는 ZIP 아카이브나 Tar ball과 비슷하지만 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. 컨테이너 객체로서의 데이터베이스 (Database As Container Object)
SQLite 아카이브는 SQLite 데이터베이스가 많은 작은 데이터 구성 요소를 담고 있는 컨테이너 객체로 동작할 수 있다는 더 일반적인 아이디어의 한 예시예요.
PostgreSQL이나 Oracle 같은 클라이언트/서버 데이터베이스에서는 사용자와 개발자가 데이터베이스를 객체가 아니라 서비스나 "노드"로 생각하는 경향이 있어요. 데이터베이스 내용이 서버의 여러 파일에, 또는 서비스 클러스터의 여러 서버에 걸쳐 퍼져 있기 때문이에요. 단일 파일이나 심지어 단일 디렉터리를 가리키며 "이것이 데이터베이스다"라고 말할 수 없어요.
반면 SQLite는 모든 내용을 디스크의 단일 파일에 저장해요. 그 단일 파일은 가리키며 "이것이 데이터베이스다"라고 말할 수 있는 것이에요. 그것은 객체처럼 동작해요. SQLite 데이터베이스 파일은 복사, 이름 변경, 이메일 첨부로 보내기, HTTP POST 요청의 인수로 전달, 또는 이미지·문서·미디어 파일 같은 다른 데이터 객체처럼 취급될 수 있어요.
연구에 따르면 많은 애플리케이션이 이미 SQLite를 컨테이너 객체로 사용하고 있어요. 예를 들어 Kennedy(SQLite 개발자와 같은 성을 가진 사람과는 무관해요)는 Android 애플리케이션의 14%가 SQLite 데이터베이스에 결코 쓰지 않는다고 보고해요. 이 애플리케이션들은 클라우드에서 전체 데이터베이스를 다운로드한 다음 필요에 따라 정보를 로컬에서 사용하는 것으로 여겨져요. 즉, 애플리케이션들은 SQLite를 데이터베이스라기보다는 질의 가능한 전송 형식(wire-transfer format)으로 사용하고 있어요.
2. SQLite 아카이브를 사용하는 애플리케이션 (Applications Using SQLite Archives)
Fossil 분산 버전 관리 시스템은 사용자에게 확인(check-in)을 Tarball, ZIP 아카이브 또는 SQLite 아카이브로 다운로드할 수 있는 옵션을 제공해요.
SQLite 아카이브의 장점 (Advantages Of SQLite Archives)
-
SQLite 아카이브는 유연해요. ZIP 아카이브와 Tarball은 파일만 저장하는 것으로 제한돼요. SQLite 아카이브는 파일과 함께 애플리케이션에 유용해 보이는 어떤 표 형식 및/또는 관계형 데이터도 저장해요.
-
SQLite 아카이브는 트랜잭션적이에요. 업데이트 중간에 크래시나 전원 손실이 발생해도 업데이트는 원자적이고 영속적이에요. 다른 프로세스가 동시에 아카이브를 업데이트하더라도 읽는 쪽은 일관되고 변하지 않는 내용 버전을 보게 돼요.
-
SQLite 아카이브는 증분적으로 업데이트될 수 있어요. 전체 아카이브를 다시 쓰지 않고도 개별 파일을 추가·제거·교체할 수 있어요.
-
SQLite 아카이브는 고수준 질의 언어(SQL)로 질의할 수 있어요. 몇 가지 예시:
- 아카이브에서 이름이 ".h"나 ".cpp"로 끝나는 모든 파일의 총 크기는 얼마인가요?
- 파일 중 25% 미만으로 압축된 파일의 비율은 얼마인가요?
- 아카이브에 실행 파일이 몇 개 있나요?
이런 질문(그 외 셀 수 없이 많은 질문)은 어떤 내용도 압축 풀거나 추출하지 않고 답할 수 있어요.
-
다른 목적으로 이미 SQLite를 사용하는 애플리케이션은 내용의 압축과 압축 해제를 처리하는 작은 확장(https://sqlite.org/src/file/ext/misc/sqlar.c)을 사용해 SQLite 아카이브 지원을 쉽게 추가할 수 있어요. 이 작은 확장조차도 아카이브의 파일이 압축되지 않은 경우에는 생략할 수 있어요. 반면 ZIP 아카이브와 Tarball을 지원하려면 별도의 라이브러리나 많은 추가 사용자 정의 코드, 때로는 둘 다가 필요해요.
-
SQLite 아카이브는 방화벽이 부과한 검열을 우회할 수 있어요. 예를 들어 "위험한" 것으로 간주되는 특정 파일 형식(예: DLL)은 ZIP 아카이브나 Tarball 안에 포장되어 있어도 Gmail과 아마도 많은 다른 이메일 서비스와 방화벽에 의해 차단될 거예요. 하지만 이런 방화벽들은 보통 SQLite 아카이브를 (아직) 알지 못하므로 내용을 SQLite 아카이브 안에 넣어 검열을 피할 수 있어요.
SQLite 아카이브의 단점 (Disadvantages Of SQLite Archives)
-
SQLite 아카이브는 비교적 새로운 형식이에요. 2014년에 처음 설명됐어요. 반면 ZIP 아카이브와 Tarball은 수십 년간 존재해 왔고 표준 형식으로 확고히 자리 잡았어요. 대부분의 프로그래머는 ZIP 아카이브나 Tarball이 무엇인지 알지만, "SQLite 아카이브"라고 말하면 "무엇이요?"라는 대답을 받을 가능성이 더 높아요. ZIP 아카이브와 Tarball을 처리하는 도구는 기본 컴퓨터에 설치되어 있을 가능성이 더 높아요.
-
SQLite 데이터베이스는 더 일반적인 형식이므로(단순히 파일 묶음을 저장하는 것보다 훨씬 더 많은 일을 하도록 설계됨) ZIP 아카이브나 Tarball 형식만큼 컴팩트하지 않아요. SQLite 아카이브는 보통 동등한 ZIP 아카이브보다 약 1% 더 커요. Tarball은 SQLite와 ZIP 아카이브에서처럼 각 파일을 개별적으로 압축하는 대신 단일 단위로 압축돼요. 이런 이유로 Tarball은 ZIP이나 SQLite 아카이브보다 작은 경향이 있어요.
예를 들어 다음 표는 SQLite 3.22.0 소스 트리의 1,743개 파일에 대한 SQLite 아카이브, ZIP 아카이브, Tarball의 상대적 크기를 보여줘요.
| SQLite 아카이브 | 10,754,048 | | ZIP 아카이브(Info-ZIP 3.0 사용) | 10,662,365 | | ZIP 아카이브(zipfile 사용) | 10,390,215 | | Tarball | 9,781,109 |
- SQLite 아카이브는 Deflate 압축 방식만 지원해요. Tarball과 ZIP 아카이브는 더 다양한 압축 방식을 지원해요.
명령줄에서 SQLite 아카이브 관리 (Managing An SQLite Archive From The Command-Line)
SQLite 아카이브를 만들고, 업데이트하고, 나열하고, 추출하는 권장 방법은 SQLite 버전 3.23.0(2018-04-02) 이상의 sqlite3.exe 명령줄 셸을 사용하는 것이에요. 이 CLI는 SQLite 아카이브를 쉽게 관리할 수 있게 해주는 -A 명령줄 옵션을 지원해요. SQLite 버전 3.22.0(2018-01-22)용 CLI에는 SQLite 아카이브 관리를 위한 .archive 명령이 있지만, 이는 셸과 상호작용해야 해요.
"example.sqlar"이라는 SQLite 아카이브의 모든 파일을 나열하려면 다음 중 하나의 명령을 사용해요.
sqlite3 example.sqlar -At
sqlite3 example.sqlar -Atv
"example.sqlar"이라는 SQLite 아카이브에서 모든 파일을 추출하려면:
sqlite3 example.sqlar -Ax
현재 디렉터리의 모든 *.txt 파일을 포함하는 "alltxt.sqlar"이라는 새 SQLite 아카이브를 만들려면:
sqlite3 alltxt.sqlar -Ac *.txt
기존 SQLite 아카이브에 파일을 추가하거나 업데이트하려면:
sqlite3 example.sqlar -Au *.md
사용 힌트와 모든 옵션 요약을 보려면 CLI에 추가 인수 없이 -A 옵션만 주면 돼요.
sqlite3 -A
파일 이름 인수가 SQLite 데이터베이스 대신 ZIP 아카이브라면 이 모든 명령은 같은 방식으로 동작해요.
1. 기타 명령줄 도구 (Other command-line tools)
ZIP 아카이브를 관리하는 "zip" 프로그램과 Tarball을 관리하는 "tar" 프로그램이 있는 것처럼, SQL 아카이브를 관리하는 "sqlar" 프로그램이 있어요. "sqlar" 프로그램은 새 SQLite 아카이브를 만들고, 기존 아카이브의 내용을 나열하고, 아카이브에서 파일을 추가·제거하고, 아카이브에서 파일을 추출할 수 있어요. 별도의 "sqlarfs" 프로그램은 SQLite 아카이브를 Fuse 파일시스템으로 마운트할 수 있어요.
애플리케이션 코드에서 SQLite 아카이브 관리 (Managing SQLite Archives From Application Code)
애플리케이션은 SQLite에 링크하고 압축·압축 해제를 처리하는 ext/misc/sqlar.c 확장을 포함함으로써 SQLite 아카이브를 쉽게 읽거나 쓸 수 있어요. sqlar.c 확장은 두 개의 새 SQL 함수를 만들어요.
sqlar_compress(X)
sqlar_compress(X) 함수는 Deflate 알고리즘을 사용해 blob X의 복사본을 압축하려고 시도하고 결과를 blob으로 반환해요. 입력 X가 압축 가능한 blob이 아니면 X의 복사본을 반환해요. 이 루틴은 SQLite 아카이브에 내용을 삽입할 때 사용돼요.
sqlar_uncompress(Y,SZ)
sqlar_uncompress(Y,SZ) 함수는 sqlar_compress(X)가 수행한 압축을 되돌려요. Y 매개변수는 압축된 내용(이전 sqlar_compress() 호출의 출력)이고, SZ는 Y를 생성한 입력 X의 원래 압축되지 않은 크기예요. SZ가 Y의 크기보다 작거나 같으면 압축이 발생하지 않았음을 나타내므로 sqlar_uncompress(Y,SZ)는 Y의 복사본을 반환해요. 그렇지 않으면 sqlar_uncompress(Y,SZ)는 Y에 Inflate 알고리즘을 실행해 압축을 풀고 원래 형태로 복원한 뒤 압축되지 않은 내용을 반환해요. 이 루틴은 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 아카이브의 특수한 경우(예를 들어 JPEG, GIF, PNG 이미지만을 저장하는 SQLite 아카이브에서 발생할 수 있어요)에서는 sqlar_compress()와 sqlar_uncompress() 함수를 사용하지 않고 내용을 데이터베이스에 삽입하거나 추출할 수 있으며, sqlar.c 확장도 필요 없어요.