Prisma는 스키마 파일(schema.prisma
)에서 모델 간의 관계를 직관적으로 정의할 수 있도록 해줍니다. @relation
속성을 사용하여 관계의 세부 사항을 설정할 수 있습니다.
기본 관계 필드 설정 원리
- 외래 키(Foreign Key): 관계의 "N"쪽에 해당하는 모델에 외래 키 필드를 정의합니다. 이 필드는 관계의 "1"쪽 모델의 기본 키를 참조합니다.
- 관계 필드: 양쪽 모델에 서로를 참조하는 관계 필드를 정의합니다. 이 필드는 데이터베이스에 실제 컬럼으로 생성되지 않고, Prisma Client가 관계를 탐색하는 데 사용됩니다.
@relation
속성: 관계 필드에@relation
속성을 사용하여 관계의 상세 정보를 설정합니다.fields
: 외래 키 필드를 지정합니다.references
: 외래 키 필드가 참조할 대상 모델의 기본 키 필드를 지정합니다.name
(선택 사항): 모호한 관계를 명확히 할 때 사용합니다.
1. 1:1 관계 (One-to-One)
1:1 관계는 한 모델의 레코드가 다른 모델의 레코드와 정확히 하나씩 연결되는 관계입니다. 일반적으로, 한쪽 모델이 다른 쪽 모델의 외래 키를 가지고 있습니다.
예시: 사용자(User)와 프로필(Profile)
한 사용자는 하나의 프로필을 가지고, 하나의 프로필은 한 명의 사용자에게 속합니다.
// schema.prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
profile Profile? // User가 Profile을 가질 수도 있고 없을 수도 있음 (Optional)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique // 외래 키 (User 모델의 id를 참조)
user User @relation(fields: [userId], references: [id]) // User 모델과의 관계 필드
}
설명:
Profile
모델에userId
필드가 외래 키로 정의되어User
모델의id
를 참조합니다.@unique
제약 조건이userId
에 추가되어 1:1 관계를 강제합니다. (하나의Profile
은 오직 하나의User
에만 연결될 수 있습니다.)Profile
모델의user
필드는User
모델을 참조하는 관계 필드이며,userId
필드를 통해User.id
를 참조하도록@relation
이 설정되어 있습니다.User
모델의profile
필드는Profile
모델을 참조하는 관계 필드입니다.?
는 프로필이 선택 사항임을 나타냅니다.
2. 1:N 관계 (One-to-Many)
1:N 관계는 한 모델의 레코드가 다른 모델의 여러 레코드와 연결될 수 있는 관계입니다. 가장 흔한 관계 유형입니다.
예시: 게시물(Post)과 댓글(Comment)
하나의 게시물은 여러 개의 댓글을 가질 수 있지만, 하나의 댓글은 오직 하나의 게시물에만 속합니다.
// schema.prisma
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id]) // Post를 작성한 User (선택 사항)
comments Comment[] // Post가 여러 개의 Comment를 가질 수 있음
}
model Comment {
id Int @id @default(autoincrement())
content String
createdAt DateTime @default(now())
postId Int // 외래 키 (Post 모델의 id를 참조)
post Post @relation(fields: [postId], references: [id]) // Comment가 속한 Post
}
// User 모델은 위에서 정의된 User 모델을 사용합니다.
// Post를 작성한 User와의 관계도 포함했습니다.
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[] // User가 여러 개의 Post를 작성할 수 있음
profile Profile?
}
설명:
Comment
모델에postId
필드가 외래 키로 정의되어Post
모델의id
를 참조합니다.Comment
모델의post
필드는Post
모델을 참조하는 관계 필드이며,postId
필드를 통해Post.id
를 참조하도록@relation
이 설정되어 있습니다.Post
모델의comments
필드는Comment
모델의 배열(Comment[]
)로 정의되어 하나의Post
가 여러 개의Comment
를 가질 수 있음을 나타냅니다.
3. M:N 관계 (Many-to-Many)
M:N 관계는 양쪽 모델의 레코드가 서로 여러 레코드와 연결될 수 있는 관계입니다. Prisma는 M:N 관계를 정의할 때 중간에 연결 테이블(Join Table)을 자동으로 생성하거나, 직접 생성할 수 있도록 지원합니다.
예시: 학생(Student)과 과목(Course)
한 학생은 여러 과목을 수강할 수 있고, 한 과목은 여러 학생이 수강할 수 있습니다.
// schema.prisma
model Student {
id Int @id @default(autoincrement())
name String
courses Course[] // Student가 여러 개의 Course를 수강할 수 있음 (자동 생성된 연결 테이블 사용)
}
model Course {
id Int @id @default(autoincrement())
title String
students Student[] // Course에 여러 명의 Student가 수강할 수 있음 (자동 생성된 연결 테이블 사용)
}
설명:
Student
와Course
모델 모두에 서로를 참조하는 관계 필드를 배열([]
)로 정의합니다.- Prisma는 이 두 모델의 M:N 관계를 처리하기 위해
_StudentToCourse
와 같은 이름의 **중간 연결 테이블(Join Table)**을 자동으로 생성합니다. 이 테이블은studentId
와courseId
라는 외래 키를 가집니다. - 개발자는 이 연결 테이블을 직접 스키마에 정의할 필요 없이 Prisma가 자동으로 처리해 줍니다.
만약 중간 연결 테이블에 추가 필드가 필요한 경우 (명시적 M:N)
수강 날짜, 성적 등 M:N 관계 자체에 속성이 필요한 경우, 중간 연결 테이블을 직접 모델로 정의해야 합니다.
예시: 학생(Student)과 과목(Course) - 수강(Enrollment) 모델을 통해 M:N 구현
// schema.prisma
model Student {
id Int @id @default(autoincrement())
name String
enrollments Enrollment[] // Student는 여러 개의 Enrollment를 가질 수 있음
}
model Course {
id Int @id @default(autoincrement())
title String
enrollments Enrollment[] // Course는 여러 개의 Enrollment를 가질 수 있음
}
// 명시적인 연결 테이블 (Enrollment)
model Enrollment {
id Int @id @default(autoincrement())
studentId Int
courseId Int
enrolledAt DateTime @default(now()) // 추가 필드
grade String? // 추가 필드
student Student @relation(fields: [studentId], references: [id])
course Course @relation(fields: [courseId], references: [id])
@@unique([studentId, courseId]) // 같은 학생이 같은 과목을 두 번 수강하지 못하도록
}
설명:
Enrollment
라는 새로운 모델을 생성하여Student
와Course
사이의 M:N 관계를 명시적으로 나타냅니다.Enrollment
모델은studentId
와courseId
라는 외래 키를 가지며, 각각Student
와Course
모델을 참조합니다.enrolledAt
,grade
와 같은 관계에 대한 추가적인 속성을Enrollment
모델에 직접 정의할 수 있습니다.@@unique([studentId, courseId])
를 통해 한 학생이 한 과목을 두 번 수강할 수 없도록 유니크 제약 조건을 추가했습니다.
공식 문서 링크
더 자세한 정보와 다양한 시나리오는 Prisma 공식 문서에서 확인하실 수 있습니다.
- Prisma 관계 (Relations): https://www.prisma.io/docs/concepts/components/prisma-schema/relations
- 1:1 관계 (One-to-one relations): https://www.prisma.io/docs/concepts/components/prisma-schema/relations/one-to-one-relations
- 1:N 관계 (One-to-many relations): https://www.prisma.io/docs/concepts/components/prisma-schema/relations/one-to-many-relations
- N:M 관계 (Many-to-many relations): https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations