ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Prisma - Relation
    ORM/Prisma 2021. 12. 29. 19:41

    Prisma Relation

    Prisma 는 RDB 기반의 여러 DBMS(PostgreSQL, MySQL, MariaDB...) 를 지원합니다.
    RDB 에서 관계는 핵심이며 이를 통해서 무결성을 보장하고, join 을 통해 우리가 원하는 데이터를 테이블 별로 가져올 수 있습니다.
    우리가 정의한 model 을 통해서 실제 DB 스키마를 생성합니다.

    Prisma 에서는 3가지의 방법으로 모델을 정의할 수 있습니다.

    • 1 : 1 : 남편과 부인의 관계, 남편은 2명 이상의 부인을 둘 수 없다.
    • 1 : N : 부모와 자식의 관계, 부모는 1명 이상의 자식들을 가질 수 있다.
    • N : M : 학원과 학생의 관계, 학원에는 여러 학생이 수강할 수 있고 학생도 여러개의 학원을 수강할 수 있다.

    관계는 Prisma 스키마에서 두 모델 간의 연결입니다.
    예를 들면, 한 명의 사용자가 여러 블로그 게시물을 가질 수 있습니다.
    이것을 1 : N 관계라고 합니다.

    1. 1 : N 관계 - 일대다

    Prisma 에서는 User 와 Post 모델 간 일대다 관계를 아래와 같이 표현합니다.

    model User {
      id        Int     @default(autoincrement()) @id
      posts     Post[]
    }
    
    model Post {
      id        Int      @default(autoincrement()) @id
      author    User?    @relation(fields: [authorId], references: [id])
      authorId  Int?
    }

    일대다 관계에서 "User 는 0 개 이상의 게시물을 가질 수 있고", "Post 에는 항상 author 가 있어야 합니다."

    Prisma 에서 User 와 Post 모델 관계는 아래와 같습니다.

    • 두 관계 필드는 authorposts 입니다.
      관계 필드들은 두 모델 간의 연결을 정의합니다. 그리고 실질적으로 Database 에는 존재하지 않습니다. 이 필드는 Prisma Client 를 생성하는 데 사용합니다.
    • 속성에서 authorId 를 참조하는 필드는 @relation 입니다. 해당 필드는 Database 에 존재합니다.
      authorIdUser 모델과 Post 모델을 연결하는 외래 키입니다.

    선택/필수 필드

    선택 필드

    User 없이 Post 데이터를 생성할 수 있습니다. User 필드와 authorId 필드에 물음표(?) 를 추가해주면 됩니다.

    model User {
      id    Int    @id @default(autoincrement())
      posts Post[]
    }
    
    model Post {
      id       Int   @id @default(autoincrement())
      author   User? @relation(fields: [authorId], references: [id])
      authorId Int?
    }

    필수 필드

    Post 데이터를 생성할 때 반드시 User 가 필요합니다.

    model User {
      id    Int    @id @default(autoincrement())
      posts Post[]
    }
    
    model Post {
      id       Int  @id @default(autoincrement())
      author   User @relation(fields: [authorId], references: [id])
      authorId Int
    }

    2. 1 : 1 관계 - 일대일

    일대일 관계는 관계의 양쪽에서 최대 하나의 레코드를 연결할 수 있는 관계입니다.

    model User {
      id      Int      @id @default(autoincrement())
      profile Profile?
    }
    
    model Profile {
      id     Int  @id @default(autoincrement())
      user   User @relation(fields: [userId], references: [id])
      userId Int 
    }

    UserProfile 을 갖지 않을수도, 가질수도 있기 때문에 profile 필드는 선택입니다.
    또한 Profile 은 항상 1 명의 User 와 연결됩니다.

    일대일 관계에서도 필수, 선택 필드를 설정할 수 있습니다.

    3. N : M 관계 - 다대다

    다대다 관계는 관계의 한쪽에 있는 0 개 이상의 레코드가 다른 쪽에 있는 0 개 이상의 레코드에 연결될 수 있는 관계를 나타냅니다.
    다대다 관계에서는 각각 테이블 간의 관계를 관리하는 추가적인 테이블을 생성해줘야 합니다.
    테이블을 생성하는 방법은 함축적(implicit) 방법과 명시적(explicit) 방법이 있습니다.

    3 - 1. 함축적 방법

    각각의 field type 을 참조하는 모델을 배열 형태로 선언합니다. 이렇게 한다면 Prisma 가 자동으로 새로운 테이블을 생성합니다.

    model Post {
      id   Int     @id @default(autoincrement())
      categories Category[]
    }
    model Category {
      id    Int    @id @default(autoincrement())
      posts Post[]
    }

    함축적 방법으로 생성된 테이블은 model 로 존재하지 않기 때문에 Prisma CRUD API 를 사용할 수 없습니다.
    즉, findUnique(), create(), ... 등을 사용할 수 없다는 의미입니다.
    하지만 Post, Category 에서 include 해서 사용할 수 있습니다.

    만약 생성해주는 테이블의 이름을 바꾸고 싶다면 @relation 을 사용하여 변경이 가능합니다.

    model Post {
      id         Int        @id @default(autoincrement())
      categories Category[] @relation("MyRelationTable")
    }
    
    model Category {
      id    Int    @id @default(autoincrement())
      posts Post[] @relation("MyRelationTable")
    }

    3 - 2. 명시적 방법

    다대다 관계를 관리하는 모델을 직접 만들어서 각각의 모델에서 생성된 Model 을 참조하는 방법입니다.

    model Post {
      id         Int                 @id @default(autoincrement())
      title      String
      categories CategoriesOnPosts[]
    }
    
    model Category {
      id    Int                 @id @default(autoincrement())
      name  String
      posts CategoriesOnPosts[]
    }
    
    model CategoriesOnPosts {
      post       Post     @relation(fields: [postId], references: [id])
      postId     Int 
      category   Category @relation(fields: [categoryId], references: [id])
      categoryId Int 
      assignedAt DateTime @default(now())
      assignedBy String
    
      @@id([postId, categoryId])
    }

    즉, 관리하는 Model 을 새로 만들어서 각각의 Model 을 참조하는 방식입니다. CategoriesOnPosts 모델을 기준으로 각각 Category, Post 모델이 1 : N 관계가 적용되고, 따라서 @relation 을 지정해줘야 합니다.

    직접 Model 을 만들기 때문에 여러 속성들을 추가할 수 있으며, Model 이 있기 때문에 Prisma CRUD API 를 사용할 수 있습니다.
    또한 테이블명, 속성 추가등을 직접 추가하고 생성이 가능합니다.

    'ORM > Prisma' 카테고리의 다른 글

    [Prisma] - 중복되는 로우 쿼리 재사용하기  (0) 2022.03.28
    NestJS, Prisma - CRUD  (0) 2021.12.26
Designed by Tistory.