개요
이 가이드 에서는 Django MongoDB 백엔드에서 컬렉션 간의 관계를 모델링하는 방법을 학습 수 있습니다. MongoDB 는 문서 데이터베이스 이므로 Django MongoDB 백엔드는 여러 컬렉션이 아닌 단일 문서 에 관련 데이터를 저장 임베디드 모델 필드를 제공합니다. 장고 MongoDB 백엔드는 상위 문서 에 관련 스칼라 값 목록을 저장 수 있는 배열 필드 도 제공합니다.
이 가이드 각 접근 방식을 사용해야 하는 경우를 설명하고 전략을 보여주는 예제를 제공합니다.
샘플 데이터
이 가이드 의 예시에서는 sample_mflix 데이터베이스 에서 다음 컬렉션을 나타내는 모델을 정의합니다.
movies: 영화에 대한 정보를 저장합니다.embedded_movies: 벡터 플롯 임베딩으로movies확장users: 영화를 본 사람에 대한 정보를 저장합니다.comments: 영화 댓글에 대한 정보를 저장합니다.
sample_mflix 데이터베이스에 대해 자세히 학습하려면 MongoDB Atlas 설명서에서 샘플 Mflix 데이터 세트 를 참조하세요.
비정규화 전략
관계형 데이터베이스는 데이터를 별도의 테이블로 정규화하고 조인을 사용하여 쿼리 시점에 관련 데이터를 결합합니다. MongoDB의 document model 사용하면 비정규화라고 하는 대신 상위 문서 내에 직접 관련 데이터를 포함할 수 있습니다. Django MongoDB 백엔드는 두 가지 접근 방식을 모두 지원하지만 성능 향상을 위해 데이터를 비정규화하는 것이 좋습니다.
비정규화하려면 다음 전략 중 하나를 선택합니다.
관련 모델 포함:
EmbeddedModelField또는EmbeddedModelArrayField를 사용하여 상위 문서 내에 관련 데이터를 저장합니다. 내장된 데이터는 상위 문서와 동일한 MongoDB 문서 에 저장되며 한 번의 읽기 작업으로 검색됩니다.배열 데이터 저장:
ArrayField를 사용하여 관련 스칼라 값 목록을 상위 문서에 직접 저장합니다. 배열 데이터는$lookup작업 없이 단일 읽기 작업으로 검색됩니다.
관련 모델 임베드
다음 조건이 모두 적용 경우 내장된 모델을 사용합니다.
관련 데이터는 항상 상위 문서 와 함께 읽습니다.
관련 데이터는 한 부모에게 속하며 여러 문서에서 공유되지 않습니다.
관련 항목의 수는 제한되어 있으며 예측 가능합니다.
관련 데이터를 포함하려면 포함된 모델 클래스를 EmbeddedModel의 하위 클래스로 정의한 다음 EmbeddedModelField 를 사용하여 상위 모델에 저장.
다음 예시 Director 임베디드 모델을 정의한 다음 Director 모델의 인스턴스 를 저장하는 Movie 모델을 정의합니다.
from django.db import models from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import EmbeddedModelField class Director(EmbeddedModel): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class Movie(models.Model): title = models.CharField(max_length=200) director = EmbeddedModelField(Director, null=True, blank=True)
임베디드 모델에 대해 자세히 학습하려면 모델 만들기 가이드에서 임베디드 모델 데이터 저장 을 참조하세요.
배열 데이터 저장
관련 스칼라 값 목록을 상위 문서에 직접 저장하려면 ArrayField 를 사용합니다. 배열 데이터는 동일한 MongoDB 문서 에 저장되며 $lookup 작업을 수행하지 않고도 단일 읽기 작업으로 검색됩니다. 다음 조건이 적용 경우 이 전략을 사용합니다.
관련 값은 문자열이나 정수와 같은 단순 스칼라입니다.
배열 크기는 제한되어 있으며 예측 가능합니다.
다음 예시 cast 필드 에 문자열 목록을 저장하는 Movie 모델을 정의합니다.
from django.db import models from django_mongodb_backend.fields import ArrayField class Movie(models.Model): title = models.CharField(max_length=200) cast = ArrayField(models.CharField(max_length=100), blank=True)
스칼라 값 대신 구조화된 문서의 배열을 저장 하려면 EmbeddedModelArrayField 를 대신 사용하세요. To learn more, see 학습 임베디드 모델 배열 데이터 저장 in the Create Models 가이드.
관계형 필드
중요
관계형 필드에 대한 쿼리는 MongoDB의 $lookup 연산자 사용하는데, 이는 대규모 컬렉션의 경우 속도가 느려질 수 있습니다. 가능하면 내장된 모델을 대신 사용합니다. 성능 고려 사항에 대해 자세히 알아보려면 성능 제한을 참조하세요.
데이터가 관계형 데이터베이스 와 유사하게 구조화되어 있고 대규모 계층적 데이터 세트를 모델링해야 하는 경우, 별도의 컬렉션에 걸쳐 문서를 연결하는 다음과 같은 관계형 Django 필드를 사용할 수 있습니다.
중요
포함된 모델 클래스 내에서 또는 ArrayField의 base_field 로 관계형 필드를 사용할 수 없습니다.
외래 키
ForeignKey 필드 사용하여 두 모델 간에 다대일 관계 생성합니다. 참조하는 모델의 각 문서 참조된 모델의 문서 하나에 연결됩니다. 다음 인수를 ForeignKey() 생성자에 전달합니다.
to: 연결할 모델 클래스on_delete: 참조된 문서 삭제 때의 삭제 동작
다음 예시 ForeignKey 필드 사용하여 Comment 모델을 Movie 모델에 연결합니다. sample_mflix.movies 문서 삭제 하면 모든 관련 sample_mflix.comments 문서도 삭제됩니다.
from django.db import models class Movie(models.Model): title = models.CharField(max_length=200) class Comment(models.Model): movie = models.ForeignKey( Movie, on_delete=models.CASCADE, ) text = models.TextField()
팁
on_delete 옵션에 대해 자세히 학습하려면 장고 문서에서 ForeignKey.on_delete 를 참조하세요.
OneToOneField
OneToOneField 필드 사용하여 두 모델 간에 일대일 관계 생성합니다. 참조하는 모델의 각 문서 참조된 모델의 정확히 하나의 문서 에 연결됩니다. 다음 인수를 OneToOneField() 생성자에 전달합니다.
to: 연결할 모델 클래스on_delete: 참조된 문서 삭제될 때의 삭제 동작
다음 예시 OneToOneField 필드 사용하여 Movie 모델에 연결되는 EmbeddedMovie 모델을 정의합니다. sample_mflix.movies 문서 삭제 하면 연결된 sample_mflix.embedded_movies 문서 도 삭제됩니다.
from django.db import models from django_mongodb_backend.fields import ArrayField class Movie(models.Model): title = models.CharField(max_length=200) class EmbeddedMovie(models.Model): movie = models.OneToOneField( Movie, on_delete=models.CASCADE, ) plot_embedding = ArrayField(models.FloatField(), blank=True)
ManyToManyField
ManyToManyField 필드 사용하여 두 모델 간에 다대다 관계 생성합니다. 두 모델의 각 문서 다른 모델의 여러 문서에 링크할 수 있습니다. 연결할 모델 클래스를 ManyToManyField() 생성자의 첫 번째 인수로 전달합니다.
다음 예시 Viewer 모델을 Movie 모델에 연결합니다. 각 뷰어는 여러 영화를 볼 수 있으며 각 영화는 여러 뷰어가 볼 수 있습니다.
from django.db import models class Movie(models.Model): title = models.CharField(max_length=200) class Viewer(models.Model): name = models.CharField(max_length=100) email = models.CharField(max_length=200) watched = models.ManyToManyField(Movie, blank=True)
관계형 데이터를 임베디드 데이터로 변환
관계형 필드를 사용하는 기존 모델이 있고 읽기 성능을 개선하려는 경우 포함된 모델을 사용하도록 변환할 수 있습니다. 이렇게 하면 $lookup 작업이 필요하지 않고 모든 관련 데이터가 단일 MongoDB 문서 에 저장됩니다.
이 예시 다음과 같은 관계형 필드가 있는 Movie 모델을 정의합니다.
ForeignKey에 연결됩니다.DirectorOneToOneField에 연결됩니다.AwardManyToManyField에 연결됩니다.Writer
from django.db import models class Director(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class Award(models.Model): wins = models.IntegerField(default=0) nominations = models.IntegerField(default=0) text = models.CharField(max_length=100) class Writer(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class Movie(models.Model): title = models.CharField(max_length=200) director = models.ForeignKey( Director, null=True, on_delete=models.SET_NULL, ) awards = models.OneToOneField( Award, null=True, on_delete=models.SET_NULL, ) writers = models.ManyToManyField(Writer, blank=True)
이러한 관계형 필드를 포함된 필드로 변환하려면 각 관련 모델을 변경하여 models.Model 대신 EmbeddedModel 를 확장한 다음, Movie 모델의 관계형 필드를 해당하는 포함된 필드로 바꿉니다.
ForeignKey을(를)EmbeddedModelField(으)로 바꿉니다.OneToOneField을(를)EmbeddedModelField(으)로 바꿉니다.ManyToManyField을(를)EmbeddedModelArrayField(으)로 바꿉니다.
다음 예시 변환된 Movie 모델을 보여줍니다.
from django.db import models from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import ( EmbeddedModelField, EmbeddedModelArrayField, ) class Director(EmbeddedModel): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class Award(EmbeddedModel): wins = models.IntegerField(default=0) nominations = models.IntegerField(default=0) class Writer(EmbeddedModel): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) class Movie(models.Model): title = models.CharField(max_length=200) director = EmbeddedModelField(Director, null=True, blank=True) awards = EmbeddedModelField(Award, null=True, blank=True) writers = EmbeddedModelArrayField(Writer, blank=True)
추가 정보
관련 모델 간에 데이터를 쿼리 방법을 학습하려면 쿼리 지정 가이드의 고급 필드 쿼리 를 참조하세요.
장고 관계형 필드에 대해 자세히 학습하려면 장고 문서의 Model field reference 를 참조하세요.
임베디드 모델에 대해 자세히 알아보려면 모델 생성 가이드의 임베디드 모델 데이터 저장 을 참조하세요.