다대다(ManyToMany)
-
두 개의 테이블(Table)이 서로의 행(행(Row))에 대해서 여러개로 연관 되어 있는 상태를 다대다(M:N)관계라고 한다.
-
이 또한 다대다를 양방향(bidirectional)이라고 한다.
-
만약 일대일(OneToOne) 관계의 테이블(Table)에서 다대다 관계로 연관 관계(Relationships)을 맺게 될 때에는 일대일(OneToOne) 테이블(Table) 중에 하나의 테이블(Table)만 관계를 맺게 된다.
다대다의 중간 테이블
- 하나의 게시글이 여러 개의 해시태그를 가질 수 있고 하나의 해시태그가 여러 개의 게시글을 가질 수 있다.

- 데이터베이스(DataBase) 특성상 다대다 관계는 중간 테이블(Table)이 생긴다.
- 만약 중간 테이블(Table)을 만들지 않고 연관 관계(Relationships)를 매핑하게 된다면 제 1정규화를 위반하게 된다.

시퀄라이즈(Sequelize)의 다대다
- .belongsToMany(테이블(Table), { through: "중간 테이블(Table) 이름"}) 형식으로 만든다.
JavaScript
다대다의 예시
-
예를 들어 한명의 학생이 여러 수업을 수강하고, 한 수업은 여러 학생을 수용한다.
-
관계를 생각 할 때 테이블(Table)로 생각하지 말고, '한 행(행(Row))'을 기준으로 생각한다.
-
그러므로 테이블 명도 '학생 목록', '수업 목록'이 아닌, 한 행을 대표할 수 있는 이름인 '학생', '수업'으로 해야 한다.
-
논리적으로 생각할 땐, 연결(매핑) 테이블(Table)은 생각하지 않다.
- 철수의 학생 코드는 학생_수업 테이블에 여러개 존재한다. (X)
- 철수는 국어, 영어, 수학 수업을 수강한다.(O)
-
항상 일대다(OneToMany)(1:N) 기준으로 생각한다.
-
다대일(ManyToOne)(N:1)보다 직관적으로 이해하기 쉽다.
- 철수가 여러 수업을 수강한다.(O)
- 국어, 영어, 수학은 철수를 수용 한다.(X)
-
이를 ERD(Entity Relationship Diagram)로 표현하면 아래와 같다.
- 학생테이블과 수업테이블이 다대다 관계로 연관되어 있다.
다대다(M:N) 구현하기
-
논리적으로 다대다관계의 표현은 가능하지만, 2개의 테이블(Table)만으로 구현하는 것은 불가능 한다.
-
다대다관계를 실제로 구현하기 위해선 각 테이블의 PrimaryKey를 외래키(FK)로 참조 하고 있는 연결테이블(매핑테이블)을 사용해야 한다.
-
이를 ERD로 표현하면 아래와 같다.
-
'학생테이블'과 '학생_수업테이블'이 일대다 관계로 연관되어 있고, '학생_수업테이블'과 '수업테이블'이 다대일 관계로 연관되어 있다.
-
예를들어 '철수'라는 학생은 '국어', '영어', '수학' 3가지의 수업을 수강하고 있고, '수학'이라는 수업은 '철수', '영희', '미자' 라는 학생을 수용 하고 있다.
-
예제를 이용해서 데이터를 3개의 테이블에 입력하면 아래와 같다.
학생
| 학생 이름 | 학생 코드 |
|---|---|
| 철수 | 1 |
| 영희 | 2 |
| 미자 | 3 |
학생_수업
- 연결테이블(매핑테이블)이다.
| 학생 코드 | 수업 코드 |
|---|---|
| 1 | a |
| 1 | b |
| 1 | c |
| 2 | c |
| 3 | c |
수업
| 수업명 | 수업 코드 |
|---|---|
| 국어 | a |
| 영어 | b |
| 수학 | c |
- 만약 철수가 듣고있는 수업들을 알고 싶다면, 철수의 학생코드 1을 조건문으로 학생_수업 테이블을 조회한다.
- 만약 영희가 국어 수업을 듣게 된다면, 영희의 학생 코드 2와 국어의 수업코드 a를 학생_수업 테이블에 삽입한다.