[day-38] Model(RDB, ERD, 1:N, N:M, 1:1)

Joohyung Park·2024년 2월 29일
0

[모두연] 오름캠프

목록 보기
71/95

관계형 데이터베이스(RDB, Relational Database)

테이블 이라고 불리는 표를 통해 데이터 집합을 표현하는 데이터베이스이다.

키의 개념과 종류

  • 기본키(Primary key) : 메인으로 사용할 키. NULL을 사용할 수 없으며, 고유한 주민등록번호, 계좌번호, 전화번호 등을 기본키로 사용할 수 있다.

  • 후보키(Candidate key) : 기본키를 제외한 고유한 키

  • 외래키(Foreign key) : 관계가 이어진 테이블에서 참고하고 있는 키

테이블

  • 튜플 : 테이블의 행

  • 속성(Attribute) : HTML의 Table Heading과 같다.

  • 도메인 : 하나의 속성에서 취할 수 있는 값의 범위. ex) 신청과목에서 전체 과목의 범위

  • 차수(Degree) : 속성의 개수

  • 기수(Cardinality) : 튜플의 개수. 속성을 제외한다.

Django는 ORM(Object Relational Mapping)이라는 기능으로 DB를 파이썬 문법으로 생성 가능하고, 이때, 테이블과 대응되는 것이 Django의 모델이다.

ERD(Entity Relation Diagram)

개체(관계형 DB에서 테이블로 표현될 수 있는 개념)들 간의 관계를 나타내는 다이어그램이다.

위 그림에서 id는 기본키(Primaryt Key, PK)로 개체들 간에 구별을 위한 식별자 역할을 한다. Django에서는 PK를 따로 설정하지 않아도 자동으로 id라는 이름의 PK 필드를 생성해준다.

이러한 ERD는 아래 서비스에서 쉽게 작성할 수 있다.

dbdiagram.io
mermaid

관계

여러 개체는 다른 개체와 관계를 가지는 경우가 많다.

테이블 간 관계를 맺을 수 있으며 그 종류는 다음과 같다.

  • 1 : N : 하나의 테이블에 여러개의 테이블이 달린 경우. ex) 게시판, 댓글
  • N : M : 여러개의 테이블에 여러개의 테이블이 달리는 구조
  • 1 : 1 : 하나의 테이블에 하나의 테이블 매칭

Django에서 모델을 통한 관계를 표시할 때, 한쪽 클래스에서의 관계를 정의하기만 하면 된다!

1 : N, 외래키


위 그림에서 학생과 학과의 관계가 1 : N의 예시라 할 수 있겠다. 한 학생은 주전공을 1개만 가질 수 있지만, 학과에는 여러 학생이 존재하기 때문이다.

Django에서는 1 : N 관계를 정의하기 위해 외래키(ForeignKey)를 사용한다. 주의할 점은 이러한 ForeignKey 필드는 1에 정의하는 것이 아니라 N에 정의한다는 것이다.

from django.db import models
from django.contrib.auth.models import User


class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    head_image = models.ImageField(upload_to="blog/images/%Y/%m/%d/", blank=True)
    file_upload = models.FileField(upload_to="blog/files/%Y/%m/%d/", blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    # '1:N'인 경우 ForeignKey는 N쪽에 작성한다.

    def __str__(self):
        return self.title

위 코드를 보면, 작성자(author) 필드는 ForeignKey의 인자로 1 : N에서 1인 User를 받고, 이 필드는 N에 해당하는 Post(게시물)에 정의되고 있다.

여기서 on_delete=models.CASCADE 는 연결된 객체가 삭제되면 해당 객체도 함께 삭제된다는 뜻이다.

Django에서 해당 필드에 객체가 없어도 1 : N으로 연결되어 있으면 1쪽에서도 접근이 가능하다.

N : M

친구 관계를 예시로 들어보면, 한 학생은 여러명의 친구를 가질 수 있으며 그 학생은 또 여러명의 친구일 수 있다. 이러한 관계를 N : M이라고 표현한다.

보통의 경우라면, 한 속성에는 하나의 값만 들어갈 수 있다. 따라서 N : M 관계에서는 중계 테이블을 사용한다.

Django에서는 ManyToManyField를 사용하여 쉽게 N : M 관계를 구현할 수 있다.

from django.db import models
from django.contrib.auth.models import User


class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    head_image = models.ImageField(
        upload_to='blog/images/%Y/%m/%d/', blank=True)
    file_upload = models.FileField(
        upload_to='blog/files/%Y/%m/%d/', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)
    author = models.ForeignKey(
        User, on_delete=models.CASCADE
    )
    # N:M 관계를 만들어줍니다. 어디서든 정의해도 상관 없습니다.
    tags = models.ManyToManyField('Tag', blank=True)

    def __str__(self):
        return self.title

위 코드에서는 게시물의 태그라는 것이 여러 게시물에 여러개 달릴 수 있으므로 ManyToManyField 를 사용하여 정의하고 있다.

1 : 1

1 : 1 관계는 OneToOneField로 표현이 가능하다. 학생과 학생증의 관계라고 생각하면 좋다.

profile
익숙해지기 위해 기록합니다

0개의 댓글