DB를 만들다 보면 Table과 Table이 M2M(Many-to-Many) 관계인 경우가 많이 생긴다. 보통은 M2M에 대한 Table을 만들기 위해서는 중간 Table을 만들어 M:1:M 관계를 만들 수 있게 해준다.
Django에서는 Model을 통해 DB 설계 시 M2M에 대해서 두 가지 방법으로 DB를 설계 할 수 있다.
- 중간 테이블 만들기
- ManytoManyField 사용하기
영화와 배우는 M2M 관계이다. 배우는 여러 영화에 출연을 하며, 영화에는 여러 배우가 출연하기 때문이다. 이런 관계를 생각하여 DB Modeling을 해보겠다.
from django.db import models
class Actor(models.Model):
first_name = models.CharField(max_length=45)
last_name = models.CharField(max_length=45)
date_of_birth = models.DateField()
class Meta:
db_table = "actors"
class Movie(models.Model):
title = models.CharField(max_length=45)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = "movies"
class ActorMovie(models.Model):
actor = models.ForeignKey("Actor", on_delete=models.CASCADE)
movie = models.ForeignKey("Movie")
class Meta:
db_table = "actor_movies"
Actor와 Movie Table의 중간 Table로 ActorMovie를 만들었다.
from django.db import models
class Actor(models.Model):
first_name = models.CharField(max_length=45)
last_name = models.CharField(max_length=45)
date_of_birth = models.DateField()
class Meta:
db_table = "actors"
class Movie(models.Model):
title = models.CharField(max_length=45)
release_date = models.DateField()
running_time = models.IntegerField()
actor = models.ManyToManyField("Actor")
class Meta:
db_table = "movies"
M2M 관계인 Table 중 하나에 ManyToManyField를 사용한 컬럼을 하나 만든다. 예제에서는 class Movie에 actor 컬럼을 ManyToManyField로 만들고 인자값으로 Actor Table을 받고 있다.
두 가지 방법은 DB에 Data를 만드는 데에도 차이가 존재한다.
# python manage.py shell
>>> from movies.models import *
>>> Actor.objects.create(first_name="강호", last_name="송", date_of_birth="1967-01-17")
>>> Actor.objects.create(first_name="동원", last_name="강", date_of_birth="1981-01-18")
>>> Movie.objects.create(title = "브로커",release_date = "2022-06-08", running_time=129)
>>> a1 = Actor.objects.get(id=1)
>>> a2 = Actor.objects.get(id=2)
>>> m1 = Movie.objects.get(id=1)
>>> ActorMovie.objects.create(actor=a1, movie=m1)
>>> ActorMovie.objects.create(actor=a2, movie=m1)
중간 테이블 사용한 M2M Modeling의 경우 Actor와 Movie에 데이터를 생성 후, 중간 테이블에 데이터를 또 생성해 연결해야 한다.
>>> from movies.models import *
>>> a1 = Actor.objects.create(first_name="강호", last_name="송", date_of_birth="1967-01-17")
>>> a1.save()
>>> a2 = Actor.objects.create(first_name="동원", last_name="강", date_of_birth="1981-01-18")
>>> a2.save()
>>> m1 = Movie.objects.create(itle = "브로커",release_date = "2022-06-08", running_time=129)
>>> m1.save()
>>> m1.actor.add(a1,a2) #ManyToMany 필드 데이터 삽입
ManyToManyField에서는 중간 테이블이 없어 따로 데이터 삽입이 필요 없다.
M2M에 대해서 중간 테이블을 사용해서 DB를 설계할 수도 있지만 ManyToManyField를 사용할 경우 더 효율적으로 DB를 설계, 생성, 조회를 할 수 있으므로 가능하면 ManyToManyField를 사용하는 것을 추천한다.