본문 바로가기

개발 공부

Prisma 스키마 (1)

Prisma 스키마

이 스키마는 SNS의 핵심 엔티티와 관계를 깔끔하게 정의한 설계도이며, Prisma가 이를 기반으로 안전하고 타입 친화적인 DB 코드를 자동 생성해 줍니다.

 

 

 


 

 

상단 설정: generator / datasource

generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
  • generator: Prisma가 TypeScript 클라이언트 코드를 자동 생성하는 설정입니다. (prisma.user.findMany() 같은 것)
  • output: 생성된 클라이언트가 저장될 경로.
  • datasource: 어떤 DB를 쓰는지(여기선 PostgreSQL), 연결 문자열은 .env의 DATABASE_URL을 사용.

 


 

전체 데이터 구조 한눈에 보기(개념도)

User 1 ───< Post >───* Like *───> User
   │            │                   
   │            └───< Comment >────┘
   │
   ├───< Follows >───> User   (팔로우 관계: follower → following)
   │
   └───< Notification > (LIKE/COMMENT/FOLLOW 알림)
  • User: 사람(계정). 글/댓글/좋아요/팔로우/알림과 연결
  • Post: 게시글
  • Comment: 댓글 (어떤 게시글에, 누가 썼는지)
  • Like: 좋아요 (같은 유저가 같은 글에 한 번만 가능)
  • Follows: 팔로우 관계 (중복 팔로우 방지용 복합 기본키)
  • Notification: 알림 (LIKE/COMMENT/FOLLOW 타입)

 

 


 

 

모델별 핵심 의미

User (사용자)

model User {
  id        String  @id @default(cuid())
  email     String  @unique
  username  String  @unique
  clerkId   String  @unique
  name      String?
  bio       String?
  image     String?
  location  String?
  website   String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  posts     Post[]
  comments  Comment[]
  likes     Like[]

  followers Follows[] @relation("following") // "나"를 팔로우하는 사람들
  following Follows[] @relation("follower")  // 내가 팔로우하는 사람들

  notifications         Notification[] @relation("userNotifications")
  notificationsCreated  Notification[] @relation("notificationCreator")
}
  • @id, @unique, @default: 기본키/유니크/기본값 설정.
  • followers/following: 동일한 Follows 테이블을 서로 다른 관점으로 보는 양방향 관계.

Post (게시글)

model Post {
  id        String   @id @default(cuid())
  authorId  String
  content   String?
  image     String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
  comments Comment[]
  likes    Like[]
  notifications Notification[]
}
  • authorId가 User.id를 참조.
  • onDelete: Cascade → 작성자 삭제 시 해당 사용자의 게시글도 함께 삭제.

Comment (댓글)

model Comment {
  id        String   @id @default(cuid())
  content   String
  authorId  String
  postId    String
  createdAt DateTime @default(now())

  author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
  post   Post @relation(fields: [postId], references: [id], onDelete: Cascade)
  notifications Notification[]

  @@index([authorId, postId])
}
  • 어떤 **글(postId)**에 누가(authorId) 썼는지.
  • @@index(...)는 해당 컬럼 조합으로 조회 성능 최적화.

Like (좋아요)

model Like {
  id        String   @id @default(cuid())
  postId    String
  userId    String
  createdAt DateTime @default(now())

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  post Post @relation(fields: [postId], references: [id], onDelete: Cascade)

  @@index([userId, postId])
  @@unique([userId, postId])
}
  • 같은 유저가 같은 글에 중복 좋아요 불가 (@@unique).

Follows (팔로우 관계)

model Follows {
  followerId  String
  followingId String
  createdAt   DateTime @default(now())

  follower  User @relation("follower",  fields: [followerId],  references: [id], onDelete: Cascade)
  following User @relation("following", fields: [followingId], references: [id], onDelete: Cascade)

  @@index([followerId, followingId])
  @@id([followerId, followingId])
}
  • **복합 기본키(@@id)**로 (followerId, followingId) 쌍의 중복 팔로우 방지.

Notification (알림)

model Notification {
  id        String   @id @default(cuid())
  userId    String          // 알림을 받는 사람
  creatorId String          // 알림을 발생시킨 사람
  type      NotificationType
  read      Boolean  @default(false)
  postId    String?
  commentId String?
  createdAt DateTime @default(now())

  user    User    @relation("userNotifications", fields: [userId], references: [id], onDelete: Cascade)
  creator User    @relation("notificationCreator", fields: [creatorId], references: [id], onDelete: Cascade)
  post    Post?   @relation(fields: [postId], references: [id], onDelete: Cascade)
  comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)

  @@index([userId, createdAt])
}
  • 누가 누구에게 어떤 타입의 알림을 보냈는지 + 관련 글/댓글 참조.
  • 받은 사람(userId), 만든 사람(creatorId)을 분리해 알림 주체/대상을 명확히 함.

enum NotificationType (알림 종류)

enum NotificationType {
  LIKE
  COMMENT
  FOLLOW
}
  • 알림 종류를 세 가지로 제한해 타입 안정성 확보.

 

 


이 스키마로 가능한 기능

  • 회원가입/로그인 후 글 작성/수정/삭제
  • 댓글/좋아요/팔로우
  • 액션 발생 시 알림 생성(자기 자신 제외)
  • 피드 페이지네이션(작성일 기준 정렬 + 커서 기반)

'개발 공부' 카테고리의 다른 글

Prisma 관계(Relation)  (0) 2025.11.02
Prisma 스키마 (2) - 인덱스, 유니크, 복합키  (0) 2025.11.01
Prop Drilling  (0) 2025.10.24
DFS, BFS  (0) 2025.10.08
Getter, Setter  (0) 2025.09.30