다대다 관계 - 소개

다대다 관계 - 소개 (Many to Many - Intro)

우리는 데이터에서 일대다(One-to-Many) 관계를 다루는 법을 봤어요.

하지만 다대다(Many-to-Many) 관계는 어떻게 다룰까요?

함께 알아봐요. 🚀

출처: 공식문서

일대다에서 시작하기

익숙하고 더 단순한 일대다 옵션부터 시작할게요.

팀(team) 테이블 하나와 히어로(hero) 테이블 하나가 있고, 하나의 팀에 많은 히어로가 있을 수 있어요.

각 팀이 여러 히어로를 가질 수 있으니, team 테이블의 열들에 히어로 ID를 전부 다 넣을 순 없어요.

하지만 각 히어로는 한 팀에만 속할 수 있으니, 히어로 테이블에는 특정 팀(테이블 team의 특정 행)을 가리키는 단일 열이 있어요.

team 테이블은 이렇게 생겼어요:

id name headquarters
1 Preventers Sharp Tower
2 Z-Force Sister Margaret's Bar

!!! tip "팁"

다른 테이블을 가리키는 외래 키가 없다는 점을 눈여겨보세요.

그리고 hero 테이블은 이렇게 생겼어요:

id name secret_name age team_id
1 Deadpond Dive Wilson null 2
2 Spider-Boy Pedro Parqueador null 1
3 Rusty-Man Tommy Sharp 48 1

hero 테이블의 team_id 열은 team 테이블에 있는 특정 팀의 ID를 가리켜요.

이렇게 각 heroteam과 연결하는 거예요:

테이블 관계

각 히어로는 하나의 연결만 가질 수 있어요. 하지만 각 팀은 많은 연결을 받을 수 있죠. 특히 Preventers 팀은 히어로가 둘이에요.

다대다 소개

그런데 Deadpond가 워낙 훌륭한 캐릭터라서, 새 Preventers 팀에도 영입됐다고 해 봅시다. 하지만 여전히 Z-Force 팀의 일원이기도 해요.

그러니 이제 많은 팀에 연결된 히어로가 필요해요. 그리고 각 팀도 여전히 많은 히어로를 받을 수 있어야 하죠. 즉 다대다 관계가 필요한 거예요.

잘 작동하지 않을 순진한 접근은 hero 테이블에 열을 더 추가하는 거예요. 열을 두 개 추가한다고 상상해 봐요. 이제 하나의 hero를 총 3개 팀까지는 연결할 수 있겠지만, 그 이상은 못 해요. 그러니 많은 팀을 지원하는 문제를 정말로 해결한 게 아니라, 아주 제한된 고정 개수만 지원한 거예요.

더 잘 할 수 있어요! 🤓

링크 테이블

hero 테이블과 team 테이블 사이의 연결을 나타내는 테이블을 하나 더 만들 수 있어요.

이 테이블이 담는 건 hero_idteam_id 두 열뿐이에요.

두 열 모두 hero 테이블과 team 테이블의 특정 행 ID를 가리키는 외래 키예요.

이게 히어로-팀 연결을 나타낼 테니, 테이블 이름은 heroteamlink라고 하죠.

이렇게 생겼어요:

다대다 테이블 관계

이제 hero 테이블에는 team_id 열이 없다는 점을 눈여겨보세요. 그 자리를 이 링크 테이블이 대신해요.

그리고 team 테이블도 이전과 마찬가지로 외래 키가 없어요.

구체적으로 새 링크 테이블 heroteamlink는 이러할 거예요:

hero_id team_id
1 1
1 2
2 1
3 1

!!! note "참고"

이 **링크 테이블**을 부르는 다른 이름들이 있어요:

* association table
* secondary table
* junction table
* intermediate table
* join table
* through table
* relationship table
* connection table

저는 "링크 테이블(link table)"이라는 용어를 써요. 짧고, 이미 쓰고 있는 다른 용어(예: "relationship")와 부딪히지 않고, 어떻게 쓰는지 기억하기 쉽기 때문이에요.

링크 기본 키

좋아요, 두 열뿐인 링크 테이블이 생겼어요. 그런데 SQL 데이터베이스는 각 행이 그 테이블의 행을 고유하게 식별하는 기본 키를 가져야 한다고 요구한다는 거 기억나세요?

그럼 이 테이블의 기본 키는 뭘까요?

각 고유 행을 어떻게 식별할까요?

이 링크 테이블의 기본 키 역할을 할 열을 하나 더 추가해야 할까요? 아뇨! 그럴 필요 없어요. 👌

두 열 모두가 이 테이블 각 행의 기본 키예요(그리고 각 행은 그 두 열만 갖고 있죠). ✨

기본 키는 단일 테이블에서 특정 행을 고유하게 식별하는 방법이에요. 하지만 꼭 단일 열일 필요는 없어요.

기본 키는 테이블의 여러 열이 합쳐져서 그 테이블에서 고유한 그룹일 수 있어요.

위 테이블을 다시 보세요. 각 행이 hero_idteam_id의 고유한 조합을 갖고 있죠?

기본 키는 중복될 수 없어요. 즉 heroteam 사이의 링크가 중복될 수 없다는 뜻인데, 바로 우리가 원하는 거예요!

예를 들어 데이터베이스는 이제 이런 중복 행 오류를 막아줘요:

hero_id team_id
1 1
1 2
2 1
3 1
3 🚨 1 🚨

히어로가 같은 팀에 두 번 속하는 건 말이 안 되잖아요, 그렇죠?

이제 두 열을 이 테이블의 기본 키로 쓰기만 하면, SQL이 heroteam 사이의 링크가 중복되는 것을 막아 줘요. ✅

요약

소개인데 요약이 나오다니, 이상하네요... 뭐 어쩌겠어요. 🤷

이제 다대다 관계에 대한 이론과, SQL의 테이블로 그걸 해결하는 법을 알게 됐어요. 🤓

이제 그걸 다루는 SQL과 코드를 어떻게 쓰는지 확인해 볼게요. 🚀

더 알아보기 (Learn more)