콘텐츠로 이동

데이터베이스 매핑

출처 URL: https://docs.prisma.io/docs/orm/prisma-schema/data-model/database-mapping

모델 및 필드 이름을 데이터베이스 테이블 및 컬럼에 매핑하는 방법을 알아보세요

Prisma schema에는 특정 데이터베이스 객체의 이름을 정의할 수 있게 해주는 메커니즘이 포함되어 있습니다. 다음을 할 수 있습니다.

  • 모델 및 필드 이름을 다른 컬렉션/테이블 및 필드/컬럼 이름에 매핑
  • 제약 조건 및 인덱스 이름 정의

컬렉션/테이블 및 필드/컬럼 이름 매핑

섹션 제목: “컬렉션/테이블 및 필드/컬럼 이름 매핑”

때때로 데이터베이스에서 엔티티를 설명하는 데 사용되는 이름이, 생성된 API에서 선호하는 이름과 일치하지 않을 수 있습니다. Prisma schema에서 이름 매핑을 사용하면, 기본 데이터베이스 이름을 변경하지 않고도 Client API의 네이밍에 영향을 줄 수 있습니다.

예를 들어 데이터베이스에서 테이블/컬렉션 이름을 짓는 일반적인 방식은 복수형과 snake_case 표기법을 사용하는 것입니다. 그러나 Prisma는 다른 네이밍 규칙(단수형, PascalCase)을 권장합니다.

@map@@map을 사용하면, 기본 데이터베이스의 테이블/컬럼 이름과 모델/필드 이름을 분리하여 Prisma Client API의 형태를 조정할 수 있습니다.

  • 컬렉션 / 테이블 이름 매핑

예를 들어 comments라는 테이블이 있는 데이터베이스를 introspect하면, 결과 Prisma 모델은 다음과 같이 보입니다:

model comments {
// Fields
}

하지만 @@map 속성을 사용하면 데이터베이스의 기본 comments 테이블 이름은 바꾸지 않고도 모델 이름을 Comment(예: 네이밍 규칙 준수)로 선택할 수 있습니다:

model Comment {
// Fields
@@map("comments")
}

이렇게 수정된 모델 정의를 사용하면 Prisma Client가 자동으로 Comment 모델을 기본 데이터베이스의 comments 테이블에 매핑합니다.

  • 필드 / 컬럼 이름 매핑

컬럼/필드 이름도 @map할 수 있습니다:

model Comment {
content String @map("comment_text")
email String @map("commenter_email")
type Enum @map("comment_type")
@@map("comments")
}

이렇게 하면 Prisma Client API에서 comment_text 컬럼은 prisma.comment.comment_text로는 사용할 수 없고, prisma.comment.content를 통해 접근할 수 있습니다.

  • enum 이름 및 값 매핑

enum 값에는 @map을, enum 자체에는 @@map을 사용할 수도 있습니다:

enum Type {
Blog,
Twitter @map("comment_twitter")
@@map("comment_source_enum")
}

이 예시에서:

  • @@map("comment_source_enum")은 enum 이름 Type을 데이터베이스의 comment_source_enum에 매핑합니다
  • @map("comment_twitter")는 enum 값 Twitter를 데이터베이스의 comment_twitter에 매핑합니다

  • 생성된 TypeScript에 미치는 영향

enum 값에 @map을 사용하면, 생성된 TypeScript enum은 매핑된 값이 아니라 schema 이름을 사용합니다:

enum Status {
PENDING @map("pending")
APPROVED @map("approved")
}

그러면 다음과 같은 TypeScript가 생성됩니다:

export const Status = {
PENDING: "PENDING",
APPROVED: "APPROVED",
} as const;

즉, Status.PENDING"pending"이 아니라 "PENDING"으로 평가됩니다. 매핑은 데이터베이스 레벨에서만 처리됩니다.

선택적으로 map 인수를 사용해 Prisma schema에서 @id, @@id, @unique, @@unique, @@index, @relation 속성의 기본 제약 조건 및 인덱스 이름을 명시적으로 정의할 수 있습니다.

데이터베이스를 introspection할 때, map 인수는 이름이 Prisma ORM의 인덱스 및 제약 조건 기본 네이밍 규칙다를 때만 schema에 렌더링됩니다.

  • 이름 있는 제약 조건의 사용 사례

제약 조건 이름을 명시적으로 지정하는 사용 사례는 다음과 같습니다.

  • 회사 정책
  • 다른 도구의 규칙
  • Prisma ORM의 인덱스 및 제약 조건 기본 네이밍 규칙

Prisma ORM 네이밍 규칙은 결정론적이기 때문에 PostgreSQL과 맞추도록 선택되었습니다. 또한 많은 데이터베이스가 이미 이 규칙과 일치하므로 이름을 렌더링할 필요가 없는 경우를 최대화하는 데 도움이 됩니다.

Prisma ORM은 기본 인덱스 및 제약 조건 이름을 생성할 때 항상 엔티티의 데이터베이스 이름을 사용합니다. 모델이 데이터 모델에서 @@map 또는 @map으로 다른 이름에 리매핑되더라도, 기본 이름 생성은 여전히 데이터베이스의 테이블 이름을 입력으로 사용합니다. 필드와 컬럼도 동일합니다.

엔티티규칙예시
기본 키{tablename}_pkeyUser_pkey
고유 제약 조건{tablename}_{column_names}_keyUser_firstName_last_Name_key
비고유 인덱스{tablename}_{column_names}_idxUser_age_idx
외래 키{tablename}_{column_names}_fkeyUser_childName_fkey

대부분의 데이터베이스에는 엔티티 이름 길이 제한이 있으므로, 데이터베이스 제한을 넘지 않도록 필요 시 이름이 잘립니다. 전체 이름이 허용 최대 길이를 넘지 않도록 _suffix 앞부분을 필요에 따라 줄입니다.

  • 기본 제약 조건 이름 사용

map 인수로 명시적 이름을 제공하지 않으면 Prisma ORM은 기본 네이밍 규칙을 따라 인덱스와 제약 조건 이름을 생성합니다.

데이터베이스를 introspection하면 인덱스 및 제약 조건 이름이 Prisma ORM의 네이밍 규칙을 따르지 않는 한 schema에 추가됩니다. 규칙을 따르면 schema 가독성을 높이기 위해 이름이 렌더링되지 않습니다. 이런 schema를 migrate할 때 Prisma는 기본 이름을 추론해 데이터베이스에 유지합니다.

  • 예시

다음 schema는 세 가지 제약 조건(@id, @unique, @relation)과 하나의 인덱스(@@index)를 정의합니다:

model User {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])
@@index([title, authorName])
}

map 인수로 명시적 이름이 제공되지 않았으므로 Prisma는 이것들이 기본 네이밍 규칙을 따른다고 가정합니다.

다음 표는 기본 데이터베이스에서 각 제약 조건과 인덱스의 이름을 보여줍니다:

제약 조건 또는 인덱스규칙 준수 여부기본 제약 조건 또는 인덱스 이름
@id (User > id 필드)User_pk
@@index (Post에서)Post_title_authorName_idx
@id (Post > id 필드)Post_pk
@relation (Post > author)Post_authorName_fkey
  • 사용자 지정 제약 조건 / 인덱스 이름 사용

map 인수를 사용해 기본 데이터베이스에서 사용자 지정 제약 조건 및 인덱스 이름을 정의할 수 있습니다.

  • 예시

다음 예시는 하나의 @id@@index에 사용자 지정 이름을 추가합니다:

model User {
id Int @id(map: "Custom_Primary_Key_Constraint_Name") @default(autoincrement())
name String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])
@@index([title, authorName], map: "My_Custom_Index_Name")
}

다음 표는 기본 데이터베이스에서 각 제약 조건과 인덱스의 이름을 보여줍니다:

제약 조건 또는 인덱스규칙 준수 여부기본 제약 조건 또는 인덱스 이름
@id (User > id 필드)아니요Custom_Primary_Key_Constraint_Name
@@index (Post에서)아니요My_Custom_Index_Name
@id (Post > id 필드)Post_pk
@relation (Post > author)Post_authorName_fkey
  • 관련: Prisma Client용 인덱스 및 기본 키 이름 지정

map 외에도 @@id@@unique 속성은 선택적 name 인수를 받아 Prisma Client API를 사용자 지정할 수 있습니다.

다음과 같은 모델에서:

model User {
firstName String
lastName String
@@id([firstName, lastName])
}

해당 기본 키를 선택하는 기본 API는 필드 조합으로 생성된 값을 사용합니다:

const user = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: "Paul",
lastName: "Panther",
},
},
});

@@id([firstName, lastName], name: "fullName")를 지정하면 Prisma Client API는 다음과 같이 변경됩니다:

const user = await prisma.user.findUnique({
where: {
fullName: {
firstName: "Paul",
lastName: "Panther",
},
},
});