KSCOLD LogoKSCOLD
Blog
Feed
Product
Admin Night
Vault
Guestbook
Info

Vault 목록

다대다(ManyToMany)

연결된 노트와 함께 읽기

다대다(ManyToMany)

2024년 9월 18일
  • 두 개의 테이블(Table)이 서로의 행(행(Row))에 대해서  여러개로 연관 되어 있는 상태를 다대다(M:N)관계라고 한다.

  • 이 또한 다대다를 양방향(bidirectional)이라고 한다.

  • 만약 일대일(OneToOne) 관계의 테이블(Table)에서 다대다 관계로 연관 관계(Relationships)을 맺게 될 때에는 일대일(OneToOne) 테이블(Table) 중에 하나의 테이블(Table)만 관계를 맺게 된다.

다대다의 중간 테이블

  • 하나의 게시글이 여러 개의 해시태그를 가질 수 있고 하나의 해시태그가 여러 개의 게시글을 가질 수 있다.

![Pasted image 20240413032627.png](Pasted image 20240413032627.png)

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

![Pasted image 20240413032925.png](Pasted image 20240413032925.png)

시퀄라이즈(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

학생_수업

  • 연결테이블(매핑테이블)이다.
학생 코드수업 코드
1a
1b
1c
2c
3c

수업

수업명수업  코드
국어a
영어b
수학c
  • 만약 철수가 듣고있는 수업들을 알고 싶다면, 철수의 학생코드 1을 조건문으로 학생_수업 테이블을 조회한다.
  • 만약 영희가 국어 수업을 듣게 된다면, 영희의 학생 코드 2와 국어의 수업코드 a를 학생_수업 테이블에 삽입한다.

Synapse Map Insight

db.Post.belongToMany(db.Hashtag, { through: 'PostHasgtag' }): db.Hashtag.belongToMany(db.Post, { through: 'PostHasgtag' }):