개요
이 가이드 에서는 Django MongoDB 백엔드에서 컬렉션 간의 관계를 모델링하는 방법을 학습 수 있습니다. MongoDB 는 문서 데이터베이스 이므로 Django MongoDB 백엔드는 여러 컬렉션이 아닌 단일 문서 에 관련 데이터를 저장 임베디드 모델 필드를 제공합니다. 장고 MongoDB 백엔드는 상위 문서 에 관련 스칼라 값 목록을 저장 수 있는 배열 필드 도 제공합니다.
이 가이드 각 접근 방식을 사용해야 하는 경우를 설명하고 전략을 보여주는 예제를 제공합니다.
샘플 데이터
이 가이드 의 예시에서는 sample_mflix 데이터베이스 에서 다음 컬렉션을 나타내는 모델을 정의합니다.
movies: 영화에 대한 정보를 저장합니다.embedded_movies: 벡터 플롯 임베딩으로movies확장users: 영화를 본 사람에 대한 정보를 저장합니다.comments: 영화 댓글에 대한 정보를 저장합니다.
데이터베이스 에 대해 자세히 sample_mflix 학습 MongoDB Atlas 설명서에서샘플 Mflix 데이터 세트를 참조하세요.
비정규화 전략
관계형 데이터베이스는 데이터를 별도의 테이블로 정규화하고 조인을 사용하여 쿼리 시점에 관련 데이터를 결합합니다. MongoDB의 문서 모델 사용하면 비정규화라고 하는 대신 상위 문서 내에 직접 관련 데이터를 포함할 수 있습니다. 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를 대신 사용하세요. 자세히 학습 모델 생성 가이드 에서 임베디드 모델 배열 데이터 저장을 참조하세요.
관계형 필드
중요
관계형 필드에 대한 쿼리는 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)
추가 정보
관련 모델 간에 데이터를 쿼리 방법을 학습 쿼리 지정 가이드 의 고급 필드 쿼리를 참조하세요.
장고 관계형 필드에 대해 자세히 학습 장고 문서에서 모델 필드 참조를 참조하세요.
임베디드 모델에 대해 자세히 학습 모델 생성 가이드 에서 임베디드 모델 데이터 저장을 참조하세요.