오늘은 너도 나도 모두가 헷갈리는 M2M 시간!
이 녀석은 왜이렇게 인싸인지..
이쪽 저쪽 테이블을 참조(Foreign
)하고 중간테이블도 맘대로 만들어준다!
(그래서 고맙지만.. 이해가 바로 되진 않아서 미워😃🔫)
ManyToMany
는 N:N관계의 테이블을 지칭할 때 사용된다.django
에서는models.ManyToMany(<테이블이름>)
으로 사용이 가능하다.
차근차근 하나씩 살펴보자.
Nike
의 모델링을 한다고 생각했을때 Product
테이블과 Color
테이블이 있다고 가정하고, 현재는 name
컬럼만 있다고 하면 아래와 같은 모습이 된다.
Product
테이블과 Color
테이블을 연결시켜주는 중간 테이블인 ProductColor
테이블이 존재한다.
그런 뒤에 데이터도 넣어준다.
데이터를 넣어줄때는 3개의 테이블에 각각 값을 다 넣어줘야 한다.
Product
의 '에어포스1'이라는 데이터가 가지고 있는 색깔들의 이름을 알고싶다.
❓ForeignKey
의 관계에서는 어떻게 값을 가져올 수 있을까❓
Product
에서 id=1의 값을 get
한다.Prodcut
는 ProductColor
와 역참조 관계이므로 product1을 _set.all()
을 이용하여 가져와 product_colors
변수에 대입한다.for...in
으로 product_colors
를 돌리면서 하나씩 .color.name
으로 알아낸다.이렇게 번거롭다면 번거롭게 찾아가야 한다.
그렇다면 M2M 관계로 한다면 뭐가 얼마나 달라질까?
모델은 Product
클래스에 color
를 하나 더 넣어주고 이것을 ManyToManyField
로 선언한다.
데이터를 넣는 과정도 ForeignKey
의 관계일때랑은 다르다.
위의 이미지에서 맨 마지막줄에 보듯이 add
를 이용하여 한번에 정의해준다. 그렇게 하면 중간 테이블인 ProductColor
에도 자동으로 값이 들어간다.
Product
의 id=1인 값을 저장한다.for...in
으로 하나씩 접근해서 color.name
을 알아낸다.단순히 보기에도 훨씬 좋아보인다!
근데 사실상 위의 예제같은 경우엔 물리적 중간테이블을 생성하지 않아도 문제는 없다.
하지만,
중간테이블에 직접 접근하기 위해서는 반드시 필요하다.
우리는 나이키의 각각의 신발에 대한 재고관리를 해야한다. 그렇다면 재고관리는 어떤 테이블에서 관리를 해야할까?
재고관리는 중간테이블에서 해야한다.
Product
에 재고를 관리한다면 에어포스1은 색깔이 어떠든 10개가 있게 된다. ❌Color
에서 관리한다면 화이트의 색상을 가진 제품들은 모두 화이트 색상이 10개가 있다. ❌이렇게 데이터가 있다면,
stock
이라는 컬럼을 만들수도 없고 stock
의 값들에 접근도 할 수 없다.따라서 중간테이블을 관리할 필요가 있다면 중간테이블이 필요하게 된다.
ManyToManyField
에서 Through
속성이 있다.
이 속성은 물리적으로 테이블을 생성했을때, 꼭 지정해줘야하는 속성이다. Through=productcolor
라고 해줘야만 중간테이블이 ProductColor
라는 것을 알 수 있다.
ForeignKey
만 선언했을 때와 M2M
을 선언했을때 뭐가 다른지add
의 사용법through
의 정확한 사용이유M2M
을 적극 활용하여 어려운 모델링을 정복해 나가야겠다!!이해안가는 내용이 있다면?? 블로깅 GoGo❗️❗️