티스토리 뷰

반응형

Prisma에서 관계형 데이터 모델링: 일대일, 일대다, 다대다 관계 구현

관계형 데이터베이스에서는 테이블 간의 관계를 설정하는 것이 중요합니다.
Prisma에서는 일대일(1:1), 일대다(1:N), 다대다(N:M) 관계를 간결하고 명확한 방식으로 정의할 수 있습니다.
이번 글에서는 Prisma를 활용한 관계형 데이터 모델링 방법과 실제 구현 코드를 소개합니다.


1. 관계형 데이터 모델링 기본 개념

데이터베이스의 관계는 테이블 간 연결 방식에 따라 다음과 같이 나뉩니다.

관계 유형 설명 예제

1:1 (일대일) 한 개의 레코드가 다른 테이블의 한 개의 레코드와 연결됨 사용자 - 프로필
1:N (일대다) 한 개의 레코드가 여러 개의 레코드와 연결됨 사용자 - 게시글
N:M (다대다) 여러 개의 레코드가 여러 개의 레코드와 연결됨 학생 - 강의

Prisma에서는 @relation과 @unique 등의 키워드를 활용하여 이러한 관계를 쉽게 정의할 수 있습니다.


2. 일대일(1:1) 관계 설정하기

예제: User와 Profile 모델 (1:1 관계)

model User {
  id       Int      @id @default(autoincrement())
  name     String
  email    String   @unique
  profile  Profile? @relation(fields: [profileId], references: [id])  // 1:1 관계
  profileId Int?    @unique
}

model Profile {
  id     Int    @id @default(autoincrement())
  bio    String
  user   User?
}

💡 설명

  • User는 하나의 Profile만 가질 수 있음
  • profileId는 @unique 제약 조건을 가져 각 사용자마다 하나의 프로필만 연결 가능
  • @relation(fields: [profileId], references: [id]): profileId는 Profile 테이블의 id를 참조

데이터 삽입 및 조회

const newUser = await prisma.user.create({
  data: {
    name: "Alice",
    email: "alice@example.com",
    profile: {
      create: { bio: "Software Engineer" }
    }
  },
  include: { profile: true }
});
console.log(newUser);

👉 include: { profile: true }를 사용하여 프로필 정보를 함께 조회할 수 있습니다.


3. 일대다(1:N) 관계 설정하기

예제: User와 Post 모델 (1:N 관계)

model User {
  id    Int     @id @default(autoincrement())
  name  String
  email String  @unique
  posts Post[]  // 1:N 관계 (사용자는 여러 개의 게시글을 가질 수 있음)
}

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

💡 설명

  • User는 여러 개의 Post(게시글)를 가질 수 있음
  • Post는 userId를 통해 어떤 사용자가 작성했는지 참조

데이터 삽입 및 조회

반응형
const newPost = await prisma.post.create({
  data: {
    title: "첫 번째 게시글",
    content: "Prisma ORM을 배워보자!",
    user: {
      connect: { id: 1 }  // 기존 사용자의 ID와 연결
    }
  }
});
console.log(newPost);

👉 connect를 사용하면 이미 존재하는 사용자와 게시글을 연결할 수 있습니다.


4. 다대다(N:M) 관계 설정하기

예제: Student와 Course 모델 (N:M 관계)

model Student {
  id      Int      @id @default(autoincrement())
  name    String
  courses Course[] @relation("Enrollment")  // 다대다 관계
}

model Course {
  id       Int       @id @default(autoincrement())
  title    String
  students Student[] @relation("Enrollment")
}

model Enrollment {
  studentId Int
  courseId  Int
  student   Student @relation(fields: [studentId], references: [id])
  course    Course  @relation(fields: [courseId], references: [id])

  @@id([studentId, courseId])  // 복합 키 (N:M 관계에서 중복 방지)
}

💡 설명

  • 학생(Student)과 강의(Course)는 N:M 관계
  • 이를 위해 중간 테이블(Enrollment)을 생성
  • @@id([studentId, courseId]): 두 개의 필드를 기본 키로 설정하여 중복 방지

데이터 삽입 및 조회

const enrollment = await prisma.enrollment.create({
  data: {
    student: { connect: { id: 1 } },  // 기존 학생과 연결
    course: { connect: { id: 101 } } // 기존 강의와 연결
  }
});
console.log(enrollment);

👉 Enrollment 테이블을 사용하여 학생과 강의를 연결할 수 있습니다.


5. Prisma 관계형 쿼리 활용하기

사용자와 게시글을 함께 조회 (1:N 관계)

const userWithPosts = await prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: true }
});
console.log(userWithPosts);

👉 include: { posts: true }를 사용하면 사용자의 모든 게시글을 함께 조회할 수 있습니다.

특정 강의를 듣고 있는 학생 조회 (N:M 관계)

const courseWithStudents = await prisma.course.findUnique({
  where: { id: 101 },
  include: { students: true }
});
console.log(courseWithStudents);

👉 include: { students: true }를 사용하여 강의에 등록된 학생 목록을 조회할 수 있습니다.


6. 결론

Prisma를 활용하면 일대일(1:1), 일대다(1:N), 다대다(N:M) 관계를 간결하게 정의할 수 있습니다.
✅ @relation을 활용하여 테이블 간의 관계를 설정
✅ connect, create 등을 사용하여 관계 데이터를 삽입 및 조회
✅ include를 사용하여 연관된 데이터를 함께 조회

다음 글에서는 **Prisma의 고급 기능(트랜잭션, 성능 최적화 등)**에 대해 다뤄보겠습니다! 🚀

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함
반응형