Published on

[Database] 설계시, 식별 비식별 관계의 장단점

Authors
  • avatar
    Name
    유사공대생
    Twitter

지금 나는 한 기업에서 현장실습 인턴을 하고 있는 중이다. 그런데 이 팀에서 팀장님이 짜신 데이터베이스 설계를 보았는데, 의문점이 한두개가 아니었다. 그래서 처음에는 왜 이렇게 설계를 하는지 의문과 화가 났다. 그러다가 내가 기술적인 부분이 부족해서 그런게 아닐까 해서 관련 자료를 찾아보고 정리해본다.

식별관계 vs 비식별관계

데이터베이스 테이블 사이에 관계는 외래 키가 기본키에 포함되는지 여부에 따라 식별관계와 비식별관계로 구분한다. 두 관계의 특징을 이해하고 각각을 어떻게 매핑하는지 알아보자.

  • 식별 관계(identifying Relationship)
  • 비식별 관계(Non-identifying Relationship)

식별 관계

식별 관계는 부모 테이블의 기본 키를 내려받아서 자식 테이블의 기본 키 + 외래 키로 사용하는 관계다.

비식별 관계

비식별 관계는 부모 테이블의 기본 키를 받아서 자식 테이블의 외래 키로만 사용하는 관계다.

비식별 관계는 외래 키에 NULL을 허용하는지에 따라 필수적 비식별 관계와 선택적 비식별 관계로 나눈다.

  • 필수적 비식별 관계: 외래 키에 NULL을 허용하지 않는다. 연관관계를 필수적으로 맺어야 한다.
  • 선택적 비식별 관계: 외래 키에 NULL을 허용한다. 연관관계를 맺을지 말지 선택할 수 있다.

데이터베이스 테이블을 설계할 때 식별 관계나 비식별 관계중 하나를 선택해야 한다. 최근에는 비식별 관계를 주로 사용하고 꼭 필요한 곳에만 식별 관계를 사용하는 추세다. JPA는 식별 관계와 비식별 관계를 모두 지원한다.

데이터베이스 설계 관점에서 보면 다음과 같은 이유로 식별관계보다는 비식별 관계를 선호한다.

  • 식별 관계는 부모 테이블의 기본 키를 자식 테이블로 전파하면서 자식 테이블의 기본 키 컬럼이 점점 늘어난다. 예를 들어 부모 테이블은 기본 키 컬럼이 하나였지만 자식 테이블은 기본 키 칼럼이 2개, 손자 테이블은 기본 키 컬럼이 3개로 점점 늘어난다. 결국 조인할 때 SQL이 복잡해지고 기본 키 인덱스가 불필요하게 커질 수 있따.

  • 식별 관계는 2개 이상의 컬럼을 합해서 복합 기본 키를 만들어야 하는 경우가 많다.

  • 식별 관계를 사용할 때 기본 키로 비즈니스 의미가 있는 자연 키 컬럼을 조합하는 경우가 많다. 반면에 비식별 관계의 기본 키는 비즈니스와 전혀 관계없는 대리 키를 주로 사용한다. 비즈니스 요구사항은 시간이 지남에 따라 언젠가는 변한다. 식별 관계의 자연 키 컬럼들이 자식에 손자까지 전파되면 변경하기 힘들다.

  • 식별 관계는 부모 테이블의 기본 키를 자식 테이블의 기본 키로 사용하므로 비식별관계보다 테이블 구조가 유연하지 못하다.

객체 관계 매핑의 관점에서 보면 다음과 같은 이유로 비식별 관계를 선호한다.

  • 일대일 관계를 제외하고 식별 관계는 2개 이상의 컬럼을 묶은 복합 기본키를 사용한다. JPA에서 복합 키는 별도의 복합 키 클래스를 만들어서 사용해야 한다. 따라서 컬럼이 하나인 기본 키를 매핑하는 것보다 많은 노력이 필요하다.

  • 비식별 관계의 기본 키는 주로 대리 키를 사용하는데 JPA는 @GenerateValue처럼 대리 키를 생성하기 위한 편리한 방법을 제공한다.

내용을 정리해보자. ORM 신규 프로젝트 진행시 추천하는 방법은 될 수 있으면 비식별 관계를 사용하고 기본 키는 Long 타입의 대리 키를 사용하는 것이다. 대리 키는 비즈니스와 아무 관련이 없다. 따라서 비즈니스가 변경되어도 유연한 대처가 가능하다는 장점이 있다. JPA는 @GeneratedValue를 통해 간편하게 대리 키를 생성할 수 있다. 그리고 식별자 컬럼이 하나여서 쉽게 매핑할 수 있다. 식별자의 데이터 타입은 Long을 추천하는데, 자바에서 Integer는 20억 정도면 끝나버리므로 데이터를 많이 저장하면 문제가 발생할 수 있다. 반면에 Long은 아주 커서(약 920경) 안전하다.

그리고 선택적 비식별 관계보다는 필수적 비식별 관계를 사용하는 것이 좋은데, 선택적인 비식별 관계는 NULL을 허용하므로 조인할 때 외부 조인을 사용해야 한다. 반면에 필수적 관계는 NOT NULL로 항상 관계가 있다는 것을 보장하므로 내부 조인만 사용해도 된다.

  • 조영한씨의 Java ORM 표준 JPA 프로그래밍 책을 읽고 정리한 내용입니다.