PostgreSQL을 설계할 때 흔히 마주하는 고민이 있습니다. 신규 데이터베이스를 만들 것인가, 기존 DB에 스키마를 추가할 것인가, 혹은 테이블스페이스를 활용할 것인가? 이번 글에서는 각 선택지가 어떤 의미를 가지며, PaaS(PostgreSQL 17 기준) 환경에서는 어떻게 접근해야 할지 정리해보겠습니다.
1. 신규 데이터베이스(DB)를 만들 때
강한 경계(격리)가 필요할 때 유리합니다.
- 백업/복구 라이프사이클 분리: 서비스별로 서로 다른 PITR(시점복구) 정책, 장기 보관 요구가 있을 때.
- 보안 경계: 팀, 벤더, 운영주체가 달라 권한을 완전히 분리해야 할 때.
- 인코딩/Collation 차이: DB 생성 시 지정 가능하므로 서로 다른 로케일이 필요할 때.
- 확장(Extensions) 충돌 방지: 특정 DB만 PostGIS, pgvector 같은 확장을 쓸 때.
- 교차 조인 불필요: PostgreSQL은 DB 간 조인이 불가능(단, FDW/dblink는 예외)하기 때문에 완전 독립 워크로드라면 DB 분리가 깔끔.
단점: DB 단위로 커넥션 풀을 따로 잡아야 하고, 운영 복잡성이 증가.
2. 같은 DB 안에서 스키마를 추가할 때
느슨한 경계가 필요한 경우 적합합니다.
- 교차 조인/외래키/트랜잭션 가능: 스키마는 같은 DB 안 네임스페이스이므로 서로 참조 가능.
- 권한 제어: 스키마 단위 USAGE/CREATE + 오브젝트 권한으로 팀별 격리 가능.
- 운영 단순화: 백업, Autovacuum, 모니터링을 한 DB 단위에서 일괄 관리.
- 커넥션 풀 효율: 여러 스키마를 같은 커넥션에서 다룰 수 있음.
주의: 같은 DB의 자원(WAL, Autovacuum, 통계)을 공유하므로 한 스키마의 대량 작업이 다른 스키마에 영향을 줄 수 있음.
3. 테이블스페이스를 고려할 때
테이블스페이스는 특정 테이블이나 인덱스를 다른 물리적 스토리지에 저장하기 위한 논리 단위입니다.
- Hot/Cold 데이터 분리: 최근 데이터는 고성능 스토리지, 과거 파티션은 저렴한 스토리지.
- 특정 인덱스 분리: 랜덤 I/O가 많은 인덱스를 IOPS 높은 볼륨에 배치.
- 임시 작업: TEMP 테이블스페이스를 분리해 쿼리 스필 I/O 격리.
⚠️ PaaS(PostgreSQL on Cloud SQL, Azure Database 등)에서는 사용자 정의 테이블스페이스 생성이 제한되는 경우가 많습니다. 이 경우 스토리지 티어 선택, 파티셔닝, 인덱스 전략으로 대체해야 합니다.
4. 의사결정 체크리스트
- 조인/트랜잭션 필요 여부 → 필요하면 스키마, 불필요하면 DB.
- 백업/복구 단위 → 서로 다른 정책 필요하면 DB 분리.
- 보안 경계 → 강한 격리 필요 시 DB, 팀 내부 구분은 스키마.
- 확장/Collation 차이 → DB 단위 분리 필요 여부 확인.
- PaaS 제약 → 테이블스페이스 지원 여부 확인, 대안은 파티셔닝/스토리지 티어.
5. 설계 예시
- 공통 서비스 + 분석: 하나의 DB에서 core, ops, bi 스키마로 분리.
- 외부 벤더 운영 모듈: 별도 DB 생성, 네트워크 레벨 접근 제어.
- 로그/이벤트: 최근 파티션은 빠른 스토리지, 과거 파티션은 저렴 스토리지. (PaaS에서 테이블스페이스 제한 시 파티셔닝으로 대체)
-- (1) 신규 DB 생성
CREATE DATABASE appdb TEMPLATE template1
LC_COLLATE 'en_US.utf8' LC_CTYPE 'en_US.utf8';
-- (2) 스키마 분리
CREATE SCHEMA core AUTHORIZATION app_owner;
CREATE SCHEMA ops AUTHORIZATION ops_owner;
GRANT USAGE ON SCHEMA core TO app_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA core TO app_role;
-- (3) (옵션) 테이블스페이스 예시 (온프렘/자유로운 환경일 때)
-- CREATE TABLESPACE fast_ts LOCATION '/mnt/fast';
-- CREATE TABLESPACE cold_ts LOCATION '/mnt/cold';
-- (4) 파티션 예시
CREATE TABLE logs (
id bigserial, ts timestamptz NOT NULL, data jsonb, PRIMARY KEY (id, ts)
) PARTITION BY RANGE (ts);
결론
- DB 분리: 강한 경계(보안, 백업, 확장 차이).
- 스키마 분리: 느슨한 경계(조인 필요, 운영 단순화).
- 테이블스페이스: 스토리지 I/O 최적화(단, PaaS 제약 고려).
PostgreSQL 17 기반 PaaS 환경에서는 스키마 중심의 설계가 일반적이고, DB/테이블스페이스 분리는 보안·복구·성능 요구사항에 따라 선택적으로 활용하는 것이 좋습니다.
'Database > postgreSQL' 카테고리의 다른 글
| PostgreSQL DBA 카탈로그/뷰 치트시트 — pg_user, pg_roles부터 실무 점검 스크립트까지 (1) | 2025.09.05 |
|---|---|
| PostgreSQL 17 + pgvector로 AI 서비스 구축하기 (RAG/추천/의미검색) (1) | 2025.09.05 |
| PostgreSQL의 jsonb와 인덱스 — 문서 DB처럼 쓰는 법 (MySQL과 비교) (0) | 2025.09.04 |
| PostgreSQL의 VACUUM — MySQL에는 없는 독특한 관리 개념 (0) | 2025.09.04 |
| PostgreSQL의 동시성 제어 (MVCC) — MySQL과의 비교 (0) | 2025.09.04 |