인프런 커뮤니티 질문&답변

tiger1303님의 프로필 이미지
tiger1303

작성한 질문수

데이터 분석 SQL Fundamentals

데이터베이스 설계에 대해 질문 드리고싶습니다

해결된 질문

작성

·

343

·

수정됨

0

강사님 안녕하십니까. 강사님 머신러닝, 딥러닝 강의도 전부 듣고 책까지 산 수강생으로서, 항상 좋은 강의 해주셔서 감사하다는 말씀 먼저 드립니다.

이번 SQL 강의는 제가 최근 스프링 프레임 워크와 스프링 데이터 JPA 를 공부하는 과정에서 데이터 베이스에 관한 공부의 필요성을 느껴 수강하게 되었고 , 그 과정에서 강의에 사용되는 테이블에 대해 궁금증이 생겨 이렇게 질문을 작성하게 되었습니다.

본 SQL 강의에서 사용되는 데이터베이스에서는 몇몇 테이블이 식별 관계로 연결되어 연관된 테이블들의 PK를 복합 식별자로 갖도록 설계되어 있던데 , 실제 업무에서도 테이블 설계 방식이 이와 같은지 궁금합니다.

스프링 데이터 JPA 강의를 수강할 때, 해당 강의의 강사 분은 각 테이블을 비 식별 관계로 설계하여, 업무의 내용과 관계없는 독립적인 ID 칼럼을 생성하여 PK로 설정하는 것이 스프링 데이터 JPA 의 코드 복잡성을 줄이고 업무 관점에서도 테이블간의 의존성을 줄여 추후에 발생하는 문제를 어느 정도 예방할 수 있기 때문에 테이블을 비 식별 관계로 설계하는 것을 선호한다고 하였는데, 권철민 강사님은 테이블을 설계하실 때 식별 관계과 비 식별 관계를 어떠한 기준으로 선택하시는지 질문드리고싶습니다.

답변 1

1

권 철민님의 프로필 이미지
권 철민
지식공유자

안녕하십니까,

AI 부터 SQL까지 제 강의를 잘 듣고 계시다니, 저도 무척이나 기쁩니다 ^^

(개인적인 생각으로는) 모델링을 할때 테이블간의 식별-비식별 관계를 지나치게 의식(?)할 필요는 없다고 생각합니다. 식별-비식별 관계는 모델링을 하다보면 '이런식으로 연결하면 되겠구나' 정도로 인식하면 충분하지, 식별-비식별이 모델링의 중요 기준이 될 수는 없다고 생각합니다.

가령 예를 들어 실습 스키마중 HR 스키마에서는 emp와 emp_salary_hist가 서로 식별 관계로 연결되어 있습니다. 그리고 dept와 emp는 서로 비식별 관계로 연결되어 있습니다. 또한 emp_dept_hist는 emp와 dept 각각 테이블로 식별 관계로 연결되어 있습니다.

보통 식별 관계로 테이블을 연결할 때는 명확하게 부모-자식 테이블인 경우가 많습니다. 예를 들어 직원(emp)데이터가 생성되어야 직원의 급여이력(emp_salary_hist) 데이터가 만들어 질 수 있습니다.

비슷하게 부서(dept)가 부모, 직원(emp)이 자식 테이블이 될 수도 있습니다(하지만 dept와 emp는 부모-자식으로 보기 좀 애매한 부분이 있습니다. 이유는 설명이 더 필요해서 글로 적기가 길어지므로 생략하도록 하겠습니다). 그럼에도 불구하고 dept와 emp가 비식별 관계로 연결된 이유는 dept와 emp가 자체적으로 중요한 마스터성 테이블이기 때문입니다.

예를 들어 dept는 자체적으로 직접적인 자식 테이블들을 가질 수 있습니다. 가령 dept의 상위 부서 변경이력이라던가..., emp역시 자체적으로 직접적인 자식 테이블들을 가지는 구조로 확장되기 쉽습니다. 만약에 emp 테이블이 dept 테이블의 직접적인 자식 테이블로 간주하고 emp 테이블의 pk를 deptno+ seqno 와 같은 구조로 만들면 emp의 직접적인 자식 테이블들은 모두 deptno + seqno를 기본적으로 상속받아서 계속 끌고 다녀야 해서 pk 컬럼 갯수가 크게 늘어날 뿐만 아니라 이들 테이블들의 식별자가 어떤 의미적인 특성이 있는지 알기가 어렵습니다.

그래서 모델링시 중요한 마스터성 테이블들은 자신만의 식별자를 가지는 구조로 만드는 경향이 있습니다.

예를 들어 고객(customer)은 customer_id, 상품(product)은 product_id, 주문(order)은 order_id, 계약(contract)은 contract_id, 배송(delivery)는 delivery_id, 부서(dept)는 dept_id 와 같이 업무적으로 중요한 뿌리(?)가 되는 마스터성 테이블들은 자신만의 식별자를 가지는 구조로 만듭니다. 물론 단독 식별자를 정하는 기준은 위의 기준만 아니라 여러가지 고려할 사항이 많지만, 가장 중요한 원칙은 위와 같습니다.

그리고 이들 마스터성 테이블들이 서로 1:m 관계일 때는 연결 시 주로 비식별 관계로 연결합니다. 가령 주문과 고객은 주문쪽의 customer_id 속성으로, 계약과 고객은 계약쪽의 customer_id 속성으로, 배송 역시 customer 테이블과 연결할때는 customer_id 속성, 주문 테이블과 연결할 때는 order_id 등과 비식별 관계로 연결합니다.

물론 중요 action 성 테이블의 경우 마스터성 테이블끼리 m:m 연결이 된다면 이들 마스터성 테이블들의 pk들이 새로운 action 테이블의 pk로 만들어 질 수도 있습니다. 예를 들어 주문상품이력은 pk가 주문번호 + 상품코드가 될 수 있습니다.

마스터성 테이블들의 속성/상태 변경이력을 관리하는 테이블들은 주로 식별관계로 연결하면 좋습니다. 예를 들어 직원의 급여 변경 이력 테이블은 직원 급여에 대한 속성을 관리하는 테이블이므로 emp_id + 이력컬럼으로 구성합니다. 고객주소 변경이력 테이블이 있다면 이것 역시 customer_id + 이력컬럼과 같이 구성합니다.

 

요약 드리자면, 업무적인 마스터성 테이블과, action 테이블, 상태/이력 변경 테이블들을 구분하고, 이를 만들어 가는 과정에서 PK를 무엇으로 할건지를 결정하는 기준을 수립하는 것이 가장 중요합니다. 식별-비식별 관계는 이러한 결정으로 만들어지는 부수적인 결과일 뿐입니다.

 

감사합니다.

 

tiger1303님의 프로필 이미지
tiger1303
질문자

감사합니다. 도움이 되었습니다 ㅎㅎ

tiger1303님의 프로필 이미지
tiger1303

작성한 질문수

질문하기