[TIL. 36]Many To Many relationship의 장점

신지원·2021년 4월 3일
3
post-thumbnail

Many to Many 관계를 설정해주면 더 좋은 이유는?

# models.py
class Allergy(models.Model):
    name = models.CharField(max_length=45)

class Drink(models.Model):
    korean_name = models.CharField(max_length=45)
    english_name = models.CharField(max_length=45)
    description = models.TextField()
    category = models.ForeignKey('Category', on_delete=models.CASCADE)
    #allergies = models.ManyToManyField(Allergy, through = "AllergyDrink")

class AllergyDrink(models.Model):
    allergy = models.ForeignKey('Allergy',on_delete=models.CASCADE)
    drink = models.ForeignKey('Drink',on_delete=models.CASCADE)

중간 테이블 AllergyDrink를 만들어주고 Allergy와 Drink를 FK로 연결해줘도 사실 데이터를 읽고 가져오는데에는 문제가 없다. 근데 굳이 many to many 로 관계설정을 해주는 이유는 뭘까?

1. 데이터를 넣을때의 차이 (create)

  • Drink와 Allergy를 Many to Many로 연결해준 경우에는 굳이 중간 테이블은 AllergyDrink를 거치지 않고 Drink를 통해 바로 Allery를 추가해 줄 수 있다.(add를 통해서)
  • 근데 만약 Drink와 Allergy를 mtm으로 연결해주지 않고 중간테이블(AllergyDrink)를 FK(Drink, Allergy)로만 연결해주면 데이터 추가할때 항상 중간테이블을 거쳐야한다.

1) MTM연결 안해준 경우

In [3]: Allergy.objects.create(name='견과류')
Out[3]: <Allergy: Allergy object (6)>

In [4]: c2 = Category.objects.get(id=2)

In [6]: Drink.objects.create(korean_name='오곡 라떼', category=c2)
Out[6]: <Drink: Drink object (3)>

In [7]: d3 = Drink.objects.get(id=3)

In [8]: a6 = Allergy.objects.get(id=6)

In [9]: AllergyDrink.objects.create(allergy=a6, drink=d3)
Out[9]: <AllergyDrink: AllergyDrink object (6)>

중간테이블인(AllergyDrink를 통해 drink에 allergy 정보를 넣어준 모습)

2) MTM 연결해준 경우

In [6]: Allergy.objects.create(name='견과류')
Out[6]: <Allergy: Allergy object (8)>

In [35]: a8 = Allergy.objects.get(id=8)

In [36]: c2 = Category.objects.get(id=2)

In [37]: d3 = Drink(korean_name='오곡라떼', category=c2)

In [38]: d3.save()

In [39]: d3.allergies.add(a8)

Drink를 통해 바로 allergy 정보를 넣어 줄 수 있다.

  • 실제 데이터베이스에서 확인한 모습
    drink테이블에 오곡라떼(id-20) AllergyDrink테이블에 오곡라떼에 해당되는 allergy가 잘 들어 간 것을 확인 할 수 있다.

2. 데이터를 가져올때도 차이 (get)

  • Many to Many(Drink-Allergy)로 연결한 경우 Drink에서 Allergy 정보(정참조)를 바로 가져올 수도 있고, Allergy에서도 Drink정보(역참조)를 바로 가져올 수 있다.
  • MTM 관계 설정을 안했을땐 항상 중간테이블인 AllergyDrink를 통해서만 가져와야 한다.

1) MTM 연결 안해준 경우

In [23]: d3 = Drink.objects.get(id=3)

In [24]: d3.allergydrink_set.all()
Out[24]: <QuerySet [<AllergyDrink: AllergyDrink object (6)>]>

In [25]: d3.allergydrink_set.get()
Out[25]: <AllergyDrink: AllergyDrink object (6)>

In [26]: d3.allergydrink_set.get().allergy
Out[26]: <Allergy: Allergy object (6)>

In [27]: d3.allergydrink_set.get().allergy.name
Out[27]: '견과류'

MTM 관계설정을 안해줬을 경우, Drink의 Allergy 정보를 가져올때 이렇게 중간 테이블 거쳐야 가져올 수 있다.

2) MTM 연결해준 경우

In [40]: d20 = Drink.objects.get(id=20)

In [41]: d20.allergies.get()
Out[41]: <Allergy: Allergy object (8)>

In [42]: d20.allergies.get().name
Out[42]: '견과류'

Drink의 Allergy 정보를 가져올때 MTM 관계 설정을 해줬기 때문에 간단하게 allergy 정보를 가져올 수 있다.

Many To Many관계를 넣어줄때 장점은 중간테이블을 거치지 않고 언제든지 데이터를 쉽게 추가하고 가져올 수 있다는 장점이 있다.
<최소한의 데이터베이스를 거쳐서 가져오는것이 가장 좋다!>

1개의 댓글

comment-user-thumbnail
2022년 3월 15일

잘보고 갑니다!

답글 달기