데이터베이스 RDBMS를 공부하면 테이블 관계가 1 대 1, 1 대 N, N 대 M 관계가 있다는 것을 쉽게 알 수 있다.
+----------+ +-----------+
| Users | | Profiles |
+----------+ +-----------+
| user_id |<--->| user_id |
| name | | bio |
+----------+ +-----------+
한 명의 사람은 하나의 프로필만 가지고 하나의 프로필은 한명의 사람 정보만 가지는
테이블 관계를 뜻하는 1 대 1 관계이다.
+----------+ +-----------+
| Users | | Orders |
+----------+ +-----------+
| user_id |<--->| user_id |
| name | | order_id |
+----------+ | order_date|
+-----------+
위 테이블의 관계는 1 대 N 관계를 나타낸다.
한 명의 유저는 여러 개의 주문을 할 수 있고 각 주문은 한 명의 주문자를
가질 수 있는 상황에서 이렇게 1대 N 관계가 생길 수 있다.
사실 여기까지는 M 대 N 관계를 정리하기 위한 빌드업이었다.
N 대 M 관계가 뭔데 이렇게 글까지 쓰게 됐을까?
어느 순간부터인가 자연스럽게 N : M 관계는 중간 테이블을 두어서 사용해야지
암기라도 한 듯이 사용하고 있다. 그게 아니라면 지금 이 테이블이 N : M 관계라는 것을
모르고 아주 비효율적으로 사용할 고 있었을 수 있다.
엥? 비효율적으로 사용했다고? N : M 관계 테이블을 만들어보자
학생은 여러 수업을 신청할 수 있고 한 수업은 여러 학생을 가질 수있는 경우
수업 ID(PK) | 과목명 | 담당 교수 | FK_학생 ID(PK) |
---|---|---|---|
1 | 데이터베이스 | 제임스 | 001 |
1 | 데이터베이스 | 제임스 | 002 |
1 | 데이터베이스 | 제임스 | 003 |
1 | 데이터베이스 | 제임스 | 004 |
2 | 자료구조 | 다니엘 | 001 |
3 | 운영체제 | 홍길동 | 002 |
4 | 프디아 | 김복순 | 003 |
학생 ID(PK) | 학생이름 | FK_수업 ID(PK) |
---|---|---|
001 | 소농민 | 1 |
002 | 손흥민 | 1 |
003 | 이강인 | 1 |
004 | 삼강인 | 1 |
001 | 소농민 | 2 |
002 | 손흥민 | 3 |
003 | 이강인 | 4 |
한눈에 보기에도 뭔가 많이 중복되는 정보가 많아 보이는데,사실 당연하다.
N : M 관계니까 여러 개를 가지고 있는 것이 당연하다.
하지만 이렇게 작성된 테이블은 다음과 같은 불편한 사항이 있다.
문제점
PK를 결정할 때 복합키를 사용하거나, 새로운 단일 PK를 두어야 한다.
Ex) 현재 수업 테이블에서는 새로운 칼럼을 추가하지 않는다면 수업ID 와 FK_학생ID 두 개를 사용해야지만
기본키를 만들 수 있다.
FK를 기준으로 다른 테이블에 조인한다면 중복되는 많아 보이는데 생긴다.
Ex) FK_학생 ID로 학생 테이블과 조인한다면 수업 ID가 중복이 된다.
서로의 정보가 필요한 경우 항상 조인이 불가피해진다.
중복된 데이터를 관리할 수 있는 중간(교차) 테이블을 두어 관리하는 건 어떨까?
N : M 관계에서 → 1 : N , M : 1 관계를 가지는 테이블로 나누어보자
학생 ID (PK) | 학생 이름 |
---|---|
001 | 소농민 |
002 | 손흥민 |
003 | 이강인 |
004 | 삼강인 |
수업 ID (PK) | 과목명 | 담당 교수 |
---|---|---|
1 | 데이터베이스 | 제임스 |
2 | 자료구조 | 다니엘 |
3 | 운영체제 | 홍길동 |
4 | 프디아 | 김복순 |
학생 ID (FK) | 수업 ID (FK) |
---|---|
001 | 1 |
001 | 2 |
002 | 1 |
002 | 3 |
003 | 1 |
003 | 4 |
004 | 1 |
N : M 테이블 관계에서는 중복데이터가 많았기 테이블 이름으로 분류가 되어있지만
해당 테이블이 정확히 어떠한 데이터를 관리하는지 이해하는 것이 어려웠다.
이렇게 테이블을 분리하면서 학생 테이블은 중복이 없는 학생 개인정보만을 관리하고
수업 테이블은 수업에 관한 정보만을 관리한다면 각 테이블의 역할이 명확하게 구분된다.
또한 학생별 수업정보를 보기 위해서 별다른 연산을 하지 않고 중간 테이블을 통해서
조회를 할 수 있다는 장점이 있다.
명확한 구분은 내가 개발할 때 쿼리문을 작성하고 테이블을 설계하는 데 큰 도움을 줄 수 있다고 생각한다.