ERD를 짜다보면 두 테이블의 관계를 M:N으로 정의해야 하는 경우가 생긴다.
예를 들어, 대학교의 데이터베이스를 생각해볼 때 학생과 강의의 테이블을 생각하면, 한 학생이 여러 개의 강의를 수강할 수 있고 한 강의도 여러 학생이 수강하므로 M:N 관계이다.
그런데 두 테이블이 M:N 관계라고 해도 ERD에서 두 테이블의 관계를 명시할 때는 절대 M:N 관계로 나타내면 안되고, 중간 매핑 테이블이 필요하다.
먼저, 매핑 테이블이 없는 관계를 생각해보자.
<학생 테이블>
학생 ID (PK) | 학생 이름 | 수강하는 강의 ID (FK) |
---|---|---|
1 | 김철수 | 1, 3 |
2 | 홍길동 | 3 |
<강의 테이블>
강의 ID (PK) | 강의명 | 수강하는 학생 ID (FK) |
---|---|---|
1 | 운영체제 | 1 |
2 | 데이터베이스 | NULL |
3 | 자료구조 | 1, 2 |
딱 보면 문제가 있다는 것을 바로 알 수 있다.
일단 원자성을 지키지 않아서 제1 정규화부터 위배되고, 강의 내역을 추가하거나 수정, 삭제를 할 때 두 테이블을 모두 수정해야 한다. 그리고 FK에 NULL 값이 많아져 비효율성을 야기할 수 있다.
학생 ID (PK) | 학생 이름 | 수강하는 강의 ID (FK) |
---|---|---|
1 | 김철수 | 1 |
1 | 김철수 | 3 |
2 | 홍길동 | 3 |
물론 이런 식으로 원자성 문제를 해결할 수 있지만, 이렇게 되면 PK의 의미가 사라진다.
즉, 정리하면 다음과 같은 문제가 발생한다.
- 원자성을 위배하거나, 원자성을 지키기 위해 레코드를 분리하면 pk의 의미가 없어진다.
- 삭제 또는 수정 시에 두 테이블을 모두 수정해야 하고, fk에 null이 많아질 수도 있다.
어떻게 해도 문제가 있다는 얘기다. 그래서 우리는 매핑 테이블을 도입한다.
아래와 같이 학생 테이블과 강의 테이블에서 FK를 삭제하고 수강내역 테이블을 추가한다.
<학생 테이블>
학생 ID (PK) | 학생 이름 |
---|---|
1 | 김철수 |
2 | 홍길동 |
<강의 테이블>
강의 ID (PK) | 강의명 |
---|---|
1 | 운영체제 |
2 | 데이터베이스 |
3 | 자료구조 |
<수강 내역 테이블>
수강 내역 ID (PK) | 학생 ID | 강의 ID |
---|---|---|
1 | 1 | 1 |
2 | 1 | 3 |
3 | 2 | 3 |
이렇게 되면 앞서 언급했던 문제는 모두 사라진다.
즉, M:N 관계 대신 매핑 테이블로 1:N 관계를 두 번 정의함으로써 문제를 해결하는 것이다.