콘텐츠로 이동

DB를 무엇으로 할 것인가 — PostgreSQL을 고른 이유

ERP의 심장은 데이터베이스입니다. 여기서 잘못 고르면 나중에 시스템을 통째로 갈아엎어야 합니다. 과거에 상용 DB들을 두루 써 본 입장에서, 이번엔 무엇을 고를지 고민이 꽤 길었습니다. 결론은 PostgreSQL이었고, 그 결정의 근거를 문서로 박아 뒀습니다. 이 글은 “왜 유행하는 매니지드 서비스 대신 직접 운영을 골랐나”를, 처음 개발하는 분도 따라올 수 있게 풀어 쓴 기록입니다.

먼저 — 데이터베이스가 뭐고, 왜 ERP에서 결정적인가

섹션 제목: “먼저 — 데이터베이스가 뭐고, 왜 ERP에서 결정적인가”

용어부터 짚겠습니다. 데이터베이스(DB)는 회사의 모든 기록 — 직원, 거래처, 재고, 결재 문서, 회계 전표 — 가 저장되는 곳입니다. 화면이나 기능은 나중에 얼마든지 바꿀 수 있습니다. 그런데 DB는 한 번 자리 잡으면 바꾸기가 가장 어렵습니다. 그 안에 모든 데이터가 들어 있고, 모든 코드가 그 구조에 의존하기 때문입니다. 그래서 ERP에서 DB 선택은 집을 지을 때 기초를 고르는 일과 같습니다.

출발점 — 상용 DB를 써 본 사람의 시각

섹션 제목: “출발점 — 상용 DB를 써 본 사람의 시각”

예전 회사들에서 상용 데이터베이스를 여럿 다뤄봤습니다. 큰 엔터프라이즈 DB도, 다른 상용 RDBMS도, 한때 유명했던 또 다른 상용 엔진도요. 이 경험이 남긴 교훈은 둘입니다.

하나, 관계형 DB의 트랜잭션 일관성은 ERP에서 타협 불가라는 것. 회계와 재고가 한 끗만 틀어져도 시스템 전체의 신뢰가 무너집니다. 이건 “성능이 좀 느려도 괜찮은” 문제가 아니라, 처음부터 보장돼 있어야 하는 토대입니다.

둘, 라이선스에 묶이면 나중에 빠져나오기가 정말 어렵다는 것. 상용 엔진은 강력하지만, 그 엔진만의 문법과 기능에 코드가 스며들면 다른 DB로 옮기는 게 사실상 불가능해집니다. 비용도 규모에 따라 가파르게 오릅니다. 1인 개발 단계에서 라이선스 비용과 이런 종속을 떠안을 이유는 없었습니다.

후보 둘 — Supabase vs PostgreSQL 직접

섹션 제목: “후보 둘 — Supabase vs PostgreSQL 직접”

오픈소스 관계형 DB로 가닥을 잡고 나니, 실제 선택지는 둘로 좁혀졌습니다. 둘 다 밑바탕이 PostgreSQL이라는 점이 핵심입니다 — 차이는 “누가 운영을 짊어지느냐”였습니다.

관점Supabase(매니지드)PostgreSQL 직접
시작 속도빠름(즉시 사용)설치·설정 필요
운영 부담낮음(플랫폼에 위임)내가 짊어짐
통제권플랫폼에 일부 종속완전한 통제
AI 벡터 검색확장으로 가능같은 DB에서 pgvector
비용 곡선규모 커지면 가팔라질 수서버 비용에 수렴
나중에 옮기기같은 엔진이라 길이 열림처음부터 자유
두 길의 차이는 "엔진"이 아니라 "누가 운영하나" Supabase (매니지드) 운영을 플랫폼이 대신 직접 운영 운영을 내가 챙김 같은 엔진: PostgreSQL → 한쪽으로 시작해도 나중에 반대편으로 옮길 길이 있다
두 후보 모두 바닥은 같은 PostgreSQL입니다. 그래서 "지금은 매니지드로 빨리 시작하고, 통제권이 필요해지면 직접 운영으로 내려오는" 경로가 열려 있습니다. 상용 엔진을 골랐다면 이 퇴로 자체가 없었을 것입니다.

왜 결국 “직접 운영”인가 — 세 가지 이유

섹션 제목: “왜 결국 “직접 운영”인가 — 세 가지 이유”

최종적으로 서버에 PostgreSQL을 직접 설치하고, ORM(코드와 DB를 안전하게 잇는 번역 계층)으로 타입 안전을 챙기는 조합을 택했습니다. 그 근거는 설계 결정 문서(ADR)에 그대로 남겼습니다. 이유는 세 가지였습니다.

  1. 도메인 횡단 트랜잭션 — 출고·전표·결재는 한 트랜잭션 안에서 함께 일관돼야 합니다. 모든 도메인이 하나의 관계형 스키마를 공유하면 이걸 가장 깔끔하게 보장합니다. (이 시스템은 200개가 넘는 표가 단일 스키마를 공유합니다.)
  2. AI를 같은 DB 안에서 — AI 검색에 쓰는 “임베딩(벡터)“을 별도의 벡터 전용 DB 없이 pgvector 확장으로 같은 PostgreSQL 안에 두었습니다. 챙겨야 할 인프라가 하나 줄었습니다.
  3. 종속 회피 — 상용 라이선스에 데어 본 경험상, 오픈소스 + 내 서버 = 언제든 옮길 수 있는 자유가 가장 중요했습니다. 미래의 선택지를 남겨 두는 것 자체가 가치입니다.
택한 것얻은 것대신 짊어진 것
단일 관계형 스키마도메인 횡단 트랜잭션 일관성스키마 변경 규율을 직접 관리
같은 DB의 pgvector벡터 DB 불필요 → 인프라 1개 ↓확장 설치·운영도 내 몫
오픈소스 + 내 서버언제든 옮길 수 있는 자유백업·보안 패치 직접

표의 오른쪽 칸을 일부러 비우지 않았습니다. 모든 선택에는 반대급부가 있습니다. “직접 운영”이 준 자유와 단순함의 대가는 “운영을 내가 다 챙겨야 한다”는 책임이었고, 그걸 알고 받아들인 결정이었습니다.

공짜 점심은 없었다 — 직접 운영의 대가

섹션 제목: “공짜 점심은 없었다 — 직접 운영의 대가”

직접 운영을 택하면 그 책임도 고스란히 따라옵니다. 가장 구체적으로 겪은 건 스키마(표 구조) 변경의 불편함이었습니다.

보통 ORM은 “이 표에 칸을 추가해줘” 같은 변경을 자동으로 적용해 주는 편리한 명령이 있습니다. 그런데 그 자동 명령은 변경을 시험해 볼 임시 DB를 잠깐 만드는데, 공유 서버의 권한 제약 때문에 그 임시 DB를 만들 수 없었습니다. 그래서 자동 명령을 포기하고, 스키마 변경을 더 수동적인 방식으로 — 변경 내용을 직접 적은 파일을 손으로 적용하는 식으로 — 관리해야 했습니다.

지금이라면 — 그리고 다른 사람에게는

섹션 제목: “지금이라면 — 그리고 다른 사람에게는”

트랜잭션 일관성이 생명인 ERP라면, 저는 여전히 관계형 + PostgreSQL을 고를 것입니다. 이건 유행이 아니라 업무의 성질에서 나오는 결론입니다. 회계·재고·결재가 얽힌 시스템은 “데이터가 절대 틀어지지 않는다”는 보장 위에서만 성립합니다.

다만 직접 운영이 모두의 정답은 아닙니다. 팀이 작고 DB 운영 인력이 없다면, 같은 PostgreSQL 위의 매니지드(Supabase 등)로 시작해 운영 부담을 미루는 것도 충분히 합리적입니다. 밑이 같은 엔진이라, 통제권이 절실해지는 시점에 직접 운영으로 옮기는 길이 열려 있기 때문입니다. “엔진은 같게, 운영 주체는 상황 따라”가 제가 권하는 절충안입니다.


이 DB가 올라간 서버 이야기는 〈서버를 세 번 옮긴 이야기〉, 그 앞단 프록시 선택은 〈리버스 프록시는 Caddy로〉로 이어집니다. 전체 그림은 〈사례연구: SL.AIMS〉에 있습니다.