[TIL] Day 43 : prisma에서 composite id 또는 composite unique constraint 설정하기

Q·2024년 6월 17일

TIL

목록 보기
44/59

prisma 에서 제공하는 기능 중에 model의 둘 이상의 field를 묶어서
1. 그 model의 id(primary key)로 설정하거나
2. uniqueness constraint로 설정하는 기능이 있다.

Composite Id 설정

  • 공식 문서 예시

model User {
  id    Int    @id @default(autoincrement())
  name  String
  post  Post[]
  likes Like[]
}

model Post {
  id      Int    @id @default(autoincrement())
  content String
  User    User?  @relation(fields: [userId], references: [id])
  userId  Int?
  likes   Like[]
}

model Like {
  postId Int
  userId Int
  User   User @relation(fields: [userId], references: [id])
  Post   Post @relation(fields: [postId], references: [id])

  @@id([postId, userId])
}

이렇게 하면 postIduserId를 묶어서 Like 테이블의 유니크한 기본 키값으로 설정할 수 있게 된다.

이름도 따로 설정해줄 수 있다.
@@id([postId, userId]) 부분에
@@id(name: "likeId", [postId, userId]) 이렇게 name: "설정할 이름" 을 추가해주면 된다.


Composite Uniqueness Constraint 설정

  • 내 프로젝트 예시

프로젝트 기획안 설명 중에
"음식점 내에서 동일한 메뉴 이름으로는 재등록이 되지 않습니다." 라는 조건이 있었다.

그런데 하나의 store에서는 menu 이름이 unique 할 지라도 menus 테이블에는 다른 stores 의 menu들도 있고, 서로 다른 store 끼리 menu 이름이 겹칠 수도 있기 때문에
menus 테이블에서 menu 이름에 unique 제약조건을 두지 못하는 문제가 있었다.

그래서 어쩔 수 없이 이를 비즈니스 로직에서만 처리하려고 생각했는데,

다행히도 튜터님 덕분에 prisma 에서 제공하는 기능 중에 composite unique 설정을 할 수 있는 방법이 있다는 것을 알게 되었다.

composite id 설정 방법과 거의 똑같이 하면 된다.

model Menu {
  id                Int                 @id @default(autoincrement())
  storeId           Int                 @map("store_id")
  name              String              
  description       String
  price             Int
  image             String
  totalReviews      Int                 @default(0) @map("total_reviews")
  averageRating     Float?              @map("average_rating")
  createdAt         DateTime            @default(now()) @map("created_at")
  updatedAt         DateTime            @updatedAt @map("updated_at")

  store             Store               @relation(fields: [storeId], references: [id], onDelete: Cascade)
  cartItem          CartItem[]
  orderItem         OrderItem[]
  reviewMenu        ReviewMenu[]

  @@unique([storeId, name])
  @@map("menus")
}

@@unique([storeId, name])
이렇게 하면 storeId 와 name(메뉴이름)을 묶어서 unique 제약조건을 걸게 되므로
같은 가게에서 같은 메뉴 이름을 등록할 수 없게 된다.
(그렇게 한다면 prisma.menu.create를 할 때 prisma 자체 에러 발생)

0개의 댓글