본문 바로가기

OS/Mac OS X

[SQLite3] 메모(Note)앱이 저장하는 데이터베이스 파일 찾아보기

자주가던 맥 관련 카페에 어떤 분이 아래와 같은 질문을 올렸다.

척보니 SQLite와 관련된 문제라는 것을 알 수 있었다.

NS접두어가 붙은 건 NextStep의 줄임말로 코코아 프레임워크의 대부분의 라이브러리들이 접두어로 사용하고 있다.

오류코드 13번에 대한 설명은 다음과 같다.

NSSQLiteErrorDomain = 13;

NSUnderlyingException = "error during SQL execution : database or disk is full";

다시말해서 데이터베이스나 디스크가 가득차서 SQL 수행이 에러가 발생했다는 것이다.

SQLite3 데이터베이스는 파일DB이다. 따라서 데이터베이스의 용량은 디스크의 용량과 직결된다.


그래서 디스크의 용량을 지워보라고 댓글을 달았다.

그랬더니 "디스크가 부족하다고 해서 계속 지우고 있는데 잘 해결이 안 되네요 ㅜㅜ"라는 댓글이 달렸다.
혹시나 했는데 정말로 디스크가 부족했던 모양이다.


메모앱이 어떻게 메모를 저장하고 있는지 궁금해졌다.
그래서 해당 DB 파일이 무엇이고 어디에 있는지 찾아보았다.

질문했던 것과 유사한 에러가 애플 disscussion에 있었다.

https://discussions.apple.com/thread/4800166

누군가 에러 덤프 파일도 첨부해서 살펴보니 파일명을 알 수 있었다.

Application Specific Information:

Error Domain=NSCocoaErrorDomain Code=256 "The file “NotesV2.storedata” couldn’t be opened."

abort() called

파일 이름을 알았으니 경로는 찾는 것은 식은 죽 먹기이다.

누군가 질문을 애플 disscussion에 물어보았다.

https://discussions.apple.com/thread/6477465

위치는 다음과 같이 있다고 한다.

~/Library/Containers/com.apple.Notes/Data/Library/Notes/NotesV2.storedata

~/Library/Containers/com.apple.Notes/Data/Library/Notes/NotesV2.storedata-shm

~/Library/Containers/com.apple.Notes/Data/Library/Notes/NotesV2.storedata-wal


터미널을 띄운다.

~/Library/Containers/com.apple.Notes/Data/Library/Notes/ 로 이동해서 DB 파일을 열어보았다.

SQLite3 파일을 여는 것은 간단하다. macOS는 기본적으로 프로그램이 설치되어 있다. https://www.sqlite.org/brew로 설치할 필요가 없다.

이제 sqlite 콘솔에 들어왔고 해당 파일이 열려있다.

무슨 테이블이 있는지 살펴보자. 명령은 .tables이다.

여러 테이블이 있는데 아마도 ZFOLDER는 메모앱 옆에 있는 폴더의 정보일 것 같고, ZNOTE가 실제 메모에 대한 항목일 것 같고, 실제 데이터 는 ZNOTEBODAY에 있을 것만 같다.

우선 테이블을 SELECT하기 전에 내용을 보기 쉽도록 포맷팅을 바꾸어본다.

헤더를 표시(.header on)하고 테이블의 형태로 보이게 한다.

우선 Z_PRIMARYKEY 테이블부터 SELECT를 해본다. (이 테이블이 컬럼이 적어서 표시에 적당하다고 생각해서이다.)

프라이머리 키 테이블에는 간략한 오버뷰의 데이터가 있는 것 같은데 정확한 의미는 잘 모르겠다.


메모의 정보가 담겨 있을 것 같아 보이는 ZNOTE 테이블을 조회해보자.

ZTITLE이라는 컬럼의 데이터 때문에 메모에 대한 내용이란 게 확실해졌다. (일부는 모자이크 처리하였다.)


이쯤해서 테이블의 스키마 정보(.schema)를 살펴보자.


ZNOTEBODY의 구조가 아래와 같이 만들어졌음을 알 수 있다.

CREATE TABLE ZNOTEBODY (
  Z_PK INTEGER PRIMARY KEY,
  Z_ENT INTEGER,
 Z_OPT INTEGER,
 ZNOTE INTEGER,
 Z10_NOTE INTEGER,
 ZHTMLSTRING VARCHAR );

아까 위에서 생활의 지혜라는 데이터의 ZBODY의 값이 15였다. 외래 키(외부 키, Foreign Key)라고 할 수 있다.
이 값은 ZBODY 테이블의 PK로 매핑된다 (PK는 Primary Key의 줄임말이다. 컬럼의 ID라고 할 수 있다.)

ZNOTEBODY 테이블은 PK 가 15인 것만으로 SELECT를 해보겠다.

여기의 내용은 메모앱의 내용과 일치한다.


이제 이글을 읽은 여러분은 macOS의 메모앱의 데이터가 저장되는 것을 파악했다.
아울러 SQL에 대해서도 알게 되었다.

참고로 SQLite3에서 .help 를 누르면 도움말이 나온다. 숙제는 나가는 방법이다.