메아리 저널

MySQL vs. PostgreSQL vs. SQLite

그러니까... 개인적으로 만드는 것에 DBMS가 필요해서 뭘 쓸지 고민하고 있었다. 이 문제의 개인적으로 만드는 것의 특징은,

  • 한 테이블에 800~1000만 row 정도를 예상하고 있다. 직접 계산해 보지는 않았으나 이 데이터의 부분집합이 500만 row라는 건 알고 있다.
  • 원래 데이터는 plain text였는데 그 날 용량은 1.5기가바이트를 넘는다.
  • 온라인으로 데이터가 추가될 수 있다. (사실은 이게 가장 중요) 그 rate는 대략 하루에 1~2만 row 정도로 잡고 있다.
  • 이 데이터들은 물론 full-text search가 되어야 한다.
  • 현재 디비 구조상 JOIN의 대상이 되는 테이블 수가 세 개에서 네 개까지 가능하다.

직접 설계를 해 보니 이거 DBA는 할 만한 일이 아니겠구나 하는 생각이 들더라. -_-

원래 쓰려던 것은 SQLite였다. 이미 이런 저런 용도로 잘 써 먹고 있었고, 웬만한 SQL-92 표준 다 지원하기 때문에 내가 하려는 삽질에는 크게 벗어나지 않을 거라 생각했다. 하지만 디비를 설계해 놓고 보니 문제점이 몇 가지 보였다.

  • full-text search에서 한국어 지원을 하려면 SQLite 전체 컴파일을 해야 한다... (근데 이건 다른 DBMS도 비슷한 수준이긴 하지만, fts3 모듈을 다시 컴파일해야 한다는 건 그 중에서도 아주 귀찮은 일이다.)
  • 한 테이블이 1기가가 넘을 것 같은데 (아까도 말했지만 이게 1000만 row 예상하는 테이블...) 이걸 나눠서 저장할 수 없으면 백업이 곤란해진다. SQLite는 테이블 단위로 다른 데이터베이스에 저장하는 기능(ATTACH/DETACH DATABASE)은 제공하지만 테이블을 나눠 저장하는 기능은 없다.
  • 설계의 편의(?)와 JOIN 수를 줄이려고(아니면 JOIN에 참여하는 테이블 수가 10개가 넘는다!) 문제의 테이블을 약간 역정규화 시켜 놓은 상태인데, 이렇게 해 놓고 보니 테이블의 일부 row에만 걸려야 하는 인덱스를 걸 수가 없다.
  • 옛날에는 MySQL을 많이 썼는데, 이건 순전히 제로보드-_- 때문이라고 밖에 못 말하겠고 그 말도 안 되게 부족한 기능에 질려서 안 쓴지 오래 된다. (SQLite로 갈아 탄 것도 그것 때문이다.) 다행히도 MySQL 4.1과 5.0에서는 내가 그렇게 까던 서브쿼리와 view, stored procedure 같은 것들이 다 추가되긴 했는데, 그럼에도 불구하고 내가 원하는 일부 기능은 아직 pre-production 상태인 MySQL 5.1에만 있어서 때려 쳤다. 역시 첫 인상이 무서운겨...

그래서 생전 쳐다 보지도 않았던 PostgreSQL을 깔고 테스트해 보고 있다. 사실 PgSQL에 관심을 가지게 된 것은 이 글을 보고 나서였는데, 그냥 교과서에서나 볼 법한 ORDBMS를 직접 사용하는 예제를 보니 이거 좋군! 싶었다. PgSQL을 쓸 경우 위에 나열했던 문제들이 대강 다음과 같이 해결된다.

  • full-text search는 어느 DBMS를 쓰나 문제가 되기 때문에 일단 생략하자. (Lucene 같은 걸 쓸 수도 있겠으나, 나는 자바를 싫어한다...)
  • table partitioning 기능은 PostgreSQL 현재 버전에서 무난하게 제공된다. 다만 자동으로 partitioning을 해 주는 기능이 없을까(예를 들어서 id가 100만을 넘으면 자동으로 새 테이블을 만들고...) 싶은데 이건 찾아 봐야 겠다.
  • 역정규화되었을 때 테이블의 일부 row에만 인덱스를 거는 문제는 두 가지 방법으로 해결할 수 있는 듯 하다. 한 가지는 테이블 상속을 이용하는 것이고 (사실은 이게 내부적으로 partitioning과 같다만) 다른 한 가지는 expression-based index를 거는 방법이다. expression-based index에 대해서는 위의 글 참고.

일단 SQLite를 위해 짜 뒀던 스키마들을 PgSQL 용으로 모두 고치고 있다. 얼마나 속도가 나올런지 테스트해 보고 나중에 후속 글을 써 보겠다.

이 글은 본래 http://arachneng.egloos.com/944389에 썼던 것을 옮겨 온 것입니다.


(rev 71b35f804c1e)