관계형 데이터베이스에서 M:N 관계에 대해 알아보자!
M:N 관계
M:N 관계는 한 쪽에서 보면 1:M 관계로 보인다. 반대 편에서도 마찬가지로 1:M 관계로 보여진다.
M:N 관계 예제
학생과 과목이라는 테이블이 있을 때 학생이 여러 개 과목을 수강하는 상황을 가정해보자.
학생 입장에서는 여러 개 과목을 수강할 수 있고, 과목 입장에서는 여러 학생이 해당 과목을 선택할 수 있다. 양쪽에서 모두 1:M 관계로 볼 수 있으므로 M:N 관계가 성립된다.
개념상으로는 M:N이 가능하다.
아래 이미지는 학생과 과목이 M:N으로 관계를 맺고 있다.
![](/post_images/Database/M-Nrelation.png)
M:N 관계를 테이블로 표현 시 문제점
🚨 M:N 관계를 풀어서 학생 테이블과 과목 테이블로 표현해보면 PK 중복 문제가 발생한다.
![](/post_images/Database/M-Ntable.png)
M:N 관계는 양쪽에서 PK 중복 문제가 발생하기 때문에 기존 두 개의 관계형 테이블로는 표현할 방법이 없다.
💡 관계라는 것은 테이블의 일반 속성끼리 연결해서 관계를 맺는 것이 아니라, PK와 FK 간의 연결을 통해 관계를 맺는 것이다. 즉, 관계를 위해선 FK 가 필요하다.
💡 M:N 관계에 참여하는 두 객체의 테이블끼리는 선천적으로 관계가 없다. 각 테이블은 스스로 존재한다. 그런데 이들 사이에 어떤 관계를 맺어줌으로써 M:N 관계를 테이블로 표현할 수 있게 된다.
어떻게 M:N 관계를 테이블로 표현할 것인가?
결국 M:N 관계를 테이블로 표현하려면 또 하나의 테이블이 필요하다.
![](/post_images/Database/M-Ntable2.png)
학생과 과목은 각자 스스로 존재하는 엔티티(개념, 테이블)이다. 그러면 수강 테이블은 스스로 존재하는 테이블일까?
NO. 수강 테이블은 학생과 과목 사이에서 행위(비즈니스 로직)를 정의하기 위해 등장한 테이블이다.
⭐️ M:N 관계는 비즈니스 관계이다.
비즈니스 관계라는 것은 나
와 상대방
간의 어떤 계약 관계를 맺어서 움직인다는 것이다.
즉, 주어
, 목적어
, 동사
가 포함되는 비즈니스 행위가 일어나서 M:N 관계를 형성하는 것이다.
예를 들어, 학생(주어)이 과목(목적어)을 수강(동사)합니다.
라는 요구사항 또는 비즈니스 행위가 존재할 때 M:N 관계를 학생
, 과목
, 수강
테이블로 표현 가능해지는 것이다.
M:N 관계에서는 테이블을 읽는 방법을 배우는 것이 매우 중요하다.
학생과 과목은 관계가 없다.
선천적으로 스스로 존재하는 학생과 과목에는 사실 어떠한 관계도 없다. 하지만 이 객체들이 관계를 맺는 순간이 온다.
언제???
비즈니스 로직(학생이 과목을 수강합니다.)이 들어오는 순간 학생과 과목 사이의 비즈니스 행위로 인해 관계가 맺어지는 것이다.
⭐️ M:N 관계라는 것은 어떤 행위가 있을 적에, 즉 비즈니스 로직이 나타날 때 스스로 존재하던 객체 간의 관계가 맺어지는 것이다.
기존 객체끼리 M:N 관계를 억지스럽게 테이블로 표현하려다 보니 PK 중복 문제가 발생했었다. 이것은 두 객체간의 비즈니스 행위를 정의하는 어떤 테이블이 생략됐기 때문에 발생한 문제였던 것이다.
Master Table
명사로서 스스로 존재할 수 있는 객체(테이블)들을 Master Table
이라고 한다.
- ex:
학생
,과목
,고객
,상품
Relation Table
동사로서 비즈니스 행위를 정의하여 M:N 관계를 표현하는 테이블을 Relation Table
이라고 한다. 참고로 관계(Relation) 테이블이 명사로서 마스터 테이블로 해석될 때도 존재한다.(관계 테이블의 PK가 또 다른 관계 테이블의 FK로 참조되는 경우이다.)
- ex:
수강
,주문
💡 REG_DATE
참고로 비즈니스 행위를 정의하는 관계(Relation) 테이블은 항상 날짜 컬럼(REG_DATE)이 필수 요소이다.
누가 무엇을 언제 ~를 했다.
를 표현할 때언제
를 날짜 컬럼이 맡게 된다.
M:N은 결국 쌍방 1:M 관계로 해석된다.
학생 - 수강
테이블 간의 관계는 1:M 관계이다.과목 - 수강
테이블 간의 관계는 1:M 관계이다.
결국 두 개의 관계를 합쳐서 M:N 관계로 해석이 되는 것이다.
M:N 관계로 해석하기 전에 살펴봐야 하는 것
- 각 Master 테이블 간 쌍방으로 1:M 관계가 없는지 살펴봐야 한다.
- 1:M 관계가 없다면 두 Master 테이블은 M:N 관계인 것이다.
M:N 관계 테이블의 기본키 체계
M:N 관계 테이블의 PK는 어떻게 잡아야 할까?
결과부터 말하자면, 비즈니스 특징에 따라 다르다.
독립형 PK
FK 의 중복을 허용해야 하는 비즈니스 상황에서는 독립형 PK를 사용한다.
![](/post_images/Database/independencePk.png)
중복을 허용하는 상황에서는 PK
를 독립적으로 설정해주자.
상속형 PK
FK의 중복을 허용하지 않는 비즈니스 상황에서는 상속형 PK를 사용한다.
![](/post_images/Database/inheritance-pk.png)
중복을 허용하지 않는 상황에서는 FK를 묶어서 복합키를 PK로 설정해주자.
💡 설계 시 주의 사항
하나의 테이블은 하나의 객체나 사물을 모델링 하는 것이다. 두 개 이상의 객체를 하나의 테이블로 모델링 하는 순간 잘못된 설계를 하는 것이다.
만약 관계 테이블에 참여하고 있는 마스터 테이블이 많다면???
하나의 레코드를 식별하기 위해 WHERE
절에 엄청 많은 FK 를 조건으로 적용해야지 식별할 수 있을 것이다.
1 |
|
실무에서는 관계 테이블을 형성하고 있는 마스터 테이블이 단순히 2개인 경우만 있는 것이 아니라 무수히 많을 수도 있다.
이런 경우 WHERE
절에서 간단히 조회하기 위해 보조키(대체키, alternate key)
를 선언해줘서 하나의 레코드를 식별하는 데 편함을 얻을 수 있다. 단, 상속형 PK 를 기본키로 사용하여 FK의 중복을 허용하지 않는다는 것을 전제로 해야 한다.
![](/post_images/Database/M-NalternateKey.png)
1 |
|
보조키(대체키)는 PK의 특징을 모두 만족하지만 PK는 아니다.
UNIQUE
하면서 NOT NULL
을 모두 만족하지만 PK
로 등록이 안된 키이다.
보조키는 관계 테이블의 조건절을 간단하게 만들어 조회를 편리하게 한다.