← posts/b.log()

blog92@web:~$ cat posts/db-design-11-identifying-and-subtypes.md

DATABASE4 min read

DB 설계 A to Z 11강 — 식별/비식별 관계, 슈퍼타입/서브타입

식별 관계와 비식별 관계의 장단점과 선택 기준, 슈퍼타입·서브타입을 단일 테이블·서브타입별 테이블·슈퍼+서브 테이블 세 가지로 변환하는 전략과 비교표를 다룬다. 시리즈 Part 2 "논리 설계"의 마지막 강이다.

Part 2의 마지막 강입니다. 관계와 상속 구조를 테이블로 옮길 때의 선택지를 정리합니다.

1. 식별 관계 vs 비식별 관계

구분식별 관계비식별 관계
정의부모 PK가 자식 PK의 일부부모 PK가 자식의 일반 컬럼(FK)
자식의 존재부모에 강하게 종속상대적으로 독립
IDEF1X 표기실선점선
예시항목처리(item_id, stage_code)주문항목(item_id PK, order_no FK)

2. 식별 관계의 장단점

장점

  • 부모 키로 자식을 조회할 때 PK 인덱스를 그대로 사용 (InnoDB에서는 물리적으로 인접 저장)
  • 조부모 키가 손자까지 전파되므로 중간 조인 없이 필터 가능
  • "부모 없이 존재할 수 없다"는 의미가 구조로 드러남

단점

  • 5강에서 본 PK 크기 전파
  • 부모 PK가 바뀌면 모든 자손의 PK가 바뀜
  • 관계가 나중에 1:N에서 N:M으로 바뀌면 PK 재설계 필요

3. 선택 기준

질문식별 쪽비식별 쪽
자식이 부모 없이 의미가 있는가?없음있음
자식이 다른 부모로 옮겨갈 수 있는가?없음 (항목처리의 소속 주문항목은 불변)있음 (주문항목의 출고건 재배정, shipment_no 변경)
계층 깊이가 3단계 이상인가?아니오예 → 중간부터 대리키
부모 키로 범위 조회가 핵심인가?예아니오
ORM을 주로 사용하는가?—예 (복합키 매핑 비용)

실무 패턴: 약한 엔티티와 교차 테이블은 식별 관계, 독립적인 업무 엔티티는 대리키 + 비식별 관계. 계층이 깊어지면 2단계까지만 식별하고 그 아래는 대리키로 끊습니다.

4. 슈퍼타입/서브타입

예제: 검수(inspection)는 외관(VI), 중량(WT), 포장(PK) 으로 나뉩니다. 공통 속성(검수 일자, 검수자, 판정)과 유형별 속성이 있습니다.

유형고유 속성
VI사진 수, 결함 등급
WT측정 무게, 허용 범위, 측정 장치 번호
PK포장자재 종류

개념 모델에서 두 가지 성질을 먼저 정합니다.

  • 배타(Exclusive) vs 중복(Overlapping): 하나의 검수가 두 유형일 수 있는가?
  • 완전(Total) vs 부분(Partial): 세 유형 외의 검수가 있는가?

5. 세 가지 변환 전략

전략 A: 단일 테이블 (Single Table / Roll-up)

sql
CREATE TABLE inspection (
    inspection_id   BIGINT PRIMARY KEY,
    inspect_type    CHAR(2) NOT NULL CHECK (inspect_type IN ('VI','WT','PK')),
    inspect_date    DATE NOT NULL,
    result          CHAR(1) NOT NULL,
    -- VI
    vi_photo_count  INT,
    vi_defect_grade CHAR(1),
    -- WT
    wt_measured_g   NUMERIC(8,2),
    wt_tolerance_g  NUMERIC(8,2),
    -- PK
    pk_material     VARCHAR(20),
    CHECK (inspect_type <> 'VI' OR vi_photo_count IS NOT NULL),
    CHECK (inspect_type <> 'WT' OR wt_measured_g  IS NOT NULL)
);

전략 B: 서브타입별 테이블 (Table per Concrete Type / Roll-down)

sql
CREATE TABLE inspection_vi (inspection_id BIGINT PRIMARY KEY, inspect_date DATE, result CHAR(1), photo_count INT, defect_grade CHAR(1));
CREATE TABLE inspection_wt (inspection_id BIGINT PRIMARY KEY, inspect_date DATE, result CHAR(1), measured_g NUMERIC(8,2), tolerance_g NUMERIC(8,2));
CREATE TABLE inspection_pk (inspection_id BIGINT PRIMARY KEY, inspect_date DATE, result CHAR(1), material VARCHAR(20));

전략 C: 슈퍼타입 + 서브타입 테이블 (Table per Type / 1:1)

sql
CREATE TABLE inspection (
    inspection_id BIGINT PRIMARY KEY,
    inspect_type  CHAR(2) NOT NULL,
    inspect_date  DATE NOT NULL,
    result        CHAR(1) NOT NULL,
    UNIQUE (inspection_id, inspect_type)
);
 
CREATE TABLE inspection_vi (
    inspection_id BIGINT PRIMARY KEY,
    inspect_type  CHAR(2) NOT NULL DEFAULT 'VI' CHECK (inspect_type = 'VI'),
    photo_count   INT NOT NULL,
    defect_grade  CHAR(1),
    FOREIGN KEY (inspection_id, inspect_type)
        REFERENCES inspection (inspection_id, inspect_type)
);

inspect_type을 서브타입에도 두고 복합 FK를 거는 기법으로, VI 서브타입 행이 WT 슈퍼타입 행을 참조하는 것을 막습니다 (배타성 보장).

6. 전략 비교

항목A. 단일 테이블B. 서브타입별C. 슈퍼+서브
전체 목록 조회빠름UNION 필요슈퍼타입만 조회
유형별 상세 조회빠름빠름조인 1회
NULL 컬럼많음없음없음
유형별 NOT NULL 강제CHECK로 가능직접 가능직접 가능
공통 속성 FK 참조쉬움어려움 (참조 대상이 3개)쉬움
유형 추가컬럼 추가테이블 추가테이블 추가
전역 ID 유일성자동별도 시퀀스 공유 필요자동
JPA 매핑SINGLE_TABLETABLE_PER_CLASSJOINED

선택 가이드

  • 서브타입 고유 속성이 적고, 전체 조회가 많다 → A
  • 다른 테이블이 "검수"를 참조한다 (예: 결함 → 검수) → C (B는 FK를 걸 수 없음)
  • 유형 간 공통 처리가 거의 없고, 각각 독립적으로 쓰인다 → B
  • 확신이 없으면 → C가 가장 무난한 기본값

11강 정리

  1. 식별 관계는 종속성과 조회 효율을, 비식별 관계는 유연성과 키 크기를 얻는다.
  2. 계층이 깊으면 중간에서 대리키로 식별 관계를 끊는다.
  3. 슈퍼/서브타입은 단일·서브타입별·슈퍼+서브 세 전략이 있고, 외부 참조 여부가 가장 중요한 기준이다.
  4. 복합 FK에 유형 컬럼을 포함하면 배타적 서브타입을 DB로 강제할 수 있다.
COMMENTS (…)

댓글을 불러오는 중이에요.

NEW COMMENT0 / 1000
⌘↵ 전송

blog92@web:~$ cd ..