DB 테이블 설계 시 자주 부딪히는 두 가지 고민: 매핑 테이블 vs 별도 엔티티, 공통 코드 vs 개별 코드

2025. 10. 18. 22:48·Database

테이블 설계에서 자주 고민하는 두 가지 포인트

  1. 매핑 테이블을 얼마나 써야 하는가?
  2. 코드 관리를 공통 코드로 묶을 것인가, 개별 테이블로 나눌 것인가?

실제 프로젝트를 하다 보면 거의 빠짐없이 부딪히는 주제입니다. 저도 여러 차례 설계하면서 이 문제로 고민했고, 각 방식마다 장단점이 분명히 있음을 깨달았습니다. 이번 글에서는 그 고민을 정리해보려 합니다.


1. 매핑 테이블 남발의 문제점

매핑 테이블은 보통 N:M 관계를 풀어내기 위해 사용합니다. 예를 들어:

  • 사용자(User) ↔ 역할(Role)
  • 게시글(Post) ↔ 태그(Tag)

이런 경우에는 매핑 테이블이 적합합니다. 하지만 모든 관계를 무조건 매핑 테이블로 풀어내다 보면 문제가 발생합니다.


(1) 장점

  • 유연성 확보: 새로운 관계가 생겨도 테이블 추가 없이 매핑 테이블에 데이터만 넣으면 됩니다.
  • 관계 독립성: 엔티티 간 결합도를 낮추고, 재사용성을 높일 수 있습니다.

(2) 문제점

  1. 조인 과다로 인한 성능 저하
    • 예: 사용자 → 역할 → 권한 같이 3~4단계 매핑을 거쳐야 데이터를 가져올 경우, SQL이 복잡해지고 성능 문제가 발생합니다.
    • 특히 PostgreSQL이나 Oracle 같은 DB에서는 실행계획이 꼬이면 예상보다 훨씬 느려질 수 있습니다.
  2. 업무 의미의 희석
    • 단순히 매핑만 두면 도메인의 의미를 담기 어렵습니다.
    • 예: 주문(Order) ↔ 상품(Product)을 매핑 테이블로만 관리하면, 수량, 단가, 할인율 같은 중요한 속성을 표현할 수 없습니다. 결국 OrderItem 같은 독립 엔티티가 필요합니다.
  3. 데이터 무결성 관리 어려움
    • 매핑 테이블만 있을 경우, 동일한 매핑이 중복 삽입될 수 있습니다.
    • 예: 같은 사용자 ↔ 역할이 여러 번 들어가는 문제. Unique 제약으로 막을 수 있지만, 도메인 의미상 한 번만 허용해야 한다면 오히려 별도 엔티티가 낫습니다.
  4. 개발 생산성 저하
    • ORM(JPA, MyBatis 등)에서 매핑 테이블을 직접 다루는 경우 코드가 장황해집니다.
    • 쿼리 작성 시에도 매번 다단계 조인을 작성해야 하므로 생산성이 떨어집니다.

(3) 적절한 활용 예시

  • 매핑 테이블로 충분한 경우
    • 사용자 ↔ 역할
    • 게시글 ↔ 태그
    • 학생 ↔ 동아리
  • 별도 엔티티로 빼야 하는 경우
    • 주문 ↔ 상품 → OrderItem
    • 직원 ↔ 프로젝트 (투입 기간, 투입 비율이 필요하다면)
    • 회원 ↔ 쿠폰 (발급 일자, 사용 여부, 만료일이 필요하다면)

즉, 추가 속성이 필요한 관계는 무조건 별도 엔티티로 분리하는 게 정답입니다.


2. 공통 코드 vs 개별 테이블

또 하나 자주 부딪히는 설계 이슈는 코드 관리입니다.

  • 모든 코드를 하나의 공통 코드 테이블에서 관리할 것인가?
  • 아니면 업무별로 개별 테이블을 둘 것인가?

(1) 공통 코드 테이블 방식

구조 예시

 
-- 공통 코드 테이블
CREATE TABLE common_code (
  code_group VARCHAR(50),
  code_value VARCHAR(50),
  code_name  VARCHAR(200),
  sort_order INT,
  use_yn CHAR(1)
);

장점

  1. 일원화 관리
    • 코드 관리 화면 하나로 모든 업무 코드를 관리할 수 있습니다.
    • 예: "성별, 국가, 권한, 주문상태" 같은 다양한 코드가 한 곳에서 관리됨.
  2. 재사용성
    • 코드 관리 로직을 공통화할 수 있어 개발 비용이 절감됩니다.
  3. 확장성
    • 새로운 코드가 필요할 때 테이블 구조를 바꿀 필요 없이 데이터만 추가하면 됩니다.

단점

  1. 업무 의미 불명확
    • code_group='ORDER_STATUS' 같은 식으로 관리되기 때문에, 어떤 코드가 어떤 테이블과 관련 있는지 직관적으로 알기 어렵습니다.
  2. 제약조건 부재
    • FK를 걸기 어렵습니다. 예를 들어 orders.status가 common_code의 ORDER_STATUS에 반드시 존재해야 한다는 제약을 DB 차원에서는 강제할 수 없습니다.
  3. 성능 저하 가능성
    • 조회할 때마다 조인을 붙여야 하고, 인덱스 설계가 복잡해질 수 있습니다.

(2) 개별 코드 테이블 방식

구조 예시

 
CREATE TABLE gender_code (
  code VARCHAR(10) PRIMARY KEY,
  name VARCHAR(50)
);

CREATE TABLE order_status_code (
  code VARCHAR(10) PRIMARY KEY,
  name VARCHAR(50)
);

장점

  1. 업무 의미 명확
    • 테이블명만 봐도 어떤 코드인지 바로 이해할 수 있습니다.
    • 예: gender_code, order_status_code
  2. 무결성 보장 가능
    • orders.status에 FK → order_status_code.code 제약을 걸 수 있습니다.
  3. 쿼리 단순화
    • 특정 코드 테이블만 조인하면 되므로, 조건절이 깔끔해집니다.

단점

  1. 테이블 관리 부담
    • 코드 종류가 많아지면 테이블 개수가 급격히 늘어납니다.
  2. 코드 관리 화면 복잡
    • 코드별로 CRUD 화면을 따로 만들어야 할 수 있습니다.
  3. 변경 시 작업량 증가
    • 새로운 코드 종류가 생길 때마다 테이블을 생성해야 합니다.

(3) 적절한 활용 예시

  • 공통 코드로 관리하기 적합한 경우
    • 비교적 단순한 코드가 많고, 빠르게 개발해야 하는 시스템
    • 예: 소규모 ERP, 관리용 백오피스, 스타트업 초기 서비스
  • 개별 테이블로 관리하기 적합한 경우
    • 코드의 업무적 의미가 강하고, FK 제약을 반드시 보장해야 하는 경우
    • 예: 대규모 금융 시스템, 공공기관 시스템, 무결성이 중요한 시스템

3. 정리 및 결론

  • 매핑 테이블
    • 단순 참조 관계라면 매핑 테이블로 충분하다.
    • 하지만 속성이 추가되는 순간, 반드시 별도 엔티티로 분리하는 것이 바람직하다.
  • 공통 코드 vs 개별 테이블
    • 빠른 개발, 유지보수의 단순함이 필요하다면 공통 코드
    • 무결성, 업무 의미, 확장성이 중요하다면 개별 테이블

👉 결론적으로,

  • 작은 규모 시스템이나 초기 단계 서비스: 공통 코드 + 매핑 테이블 적극 활용
  • 대규모, 무결성이 중요한 시스템: 개별 코드 테이블 + 의미 있는 엔티티 설계

이렇게 보면 단순히 "무조건 이게 옳다"가 아니라, 상황에 따라 선택지가 달라지는 문제라는 것을 알 수 있습니다.
저 역시 프로젝트 상황에 따라 두 가지 접근을 혼합해서 사용하는 경우가 많습니다.

저작자표시 (새창열림)
'Database' 카테고리의 다른 글
  • 인덱스(Index)와 실행계획(Explain Plan)
  • DB Isolation Level
  • 데이터베이스 락(Lock)
쭈니어 개발자
쭈니어 개발자
    홈 |
  • 쭈니어 개발자
    주니어 개발자 공부 기록
    쭈니어 개발자
  • 글쓰기 관리
  • 전체
    오늘
    어제
  • GitHub

    Notion

    • 분류 전체보기 (134)
      • Frontend (4)
      • Backend (21)
      • Database (4)
      • Data Structure & Algorithm (41)
      • Network (16)
      • IT Education (48)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    트리의 지름
    코테
    백준
    자바
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.4
쭈니어 개발자
DB 테이블 설계 시 자주 부딪히는 두 가지 고민: 매핑 테이블 vs 별도 엔티티, 공통 코드 vs 개별 코드
상단으로

티스토리툴바