Node 강의/숙련

1-11 [게시판 프로젝트] 시작하기 (DB 설계 및 Prisma 모델 정의)

kagan-draca 2024. 9. 8. 17:09

1. [게시판 프로젝트] 설계하기

 

각 테이블 간의 관계 및 요구사항을 정리하면,

 

사용자(Users)는 1개의 사용자 정보(UserInfo)를 가진다.

= Users 테이블과 UserInfo 테이블은 1 : 1 관계를 가진다.

 

사용자(Users)는 여러 개의 게시글(Posts)을 등록할 수 있다.

= Users 테이블과 Posts 테이블은 1 : N 관계를 가진다.

 

사용자(Users)는 여러 개의 댓글(Comments)을 작성할 수 있다.

= Users 테이블과 Comments 테이블은 1 : N 관계를 가진다.

 

하나의 게시글(Posts)은 여러 개의 댓글(Comments)이 작성될 수 있다.

= Posts 테이블과 Comments 테이블은 1 : N 관계를 가진다.

 

2. [게시판 프로젝트] 디렉토리 구성하기

프로젝트 초기화

  • yarn - init
  • package.json              "type" : "module"
  • package.json              "main" : "서버와 연결될.js 파일"
  • package.json              "scripts" : { "dev" : "nodemon 서버와 연결될.js 파일"  }
  • npx prisma init

 

필요한 패키지 목록

  • express                          yarn add express
  • prisma                            yarn add prisma
  • prisma/client                   yarn add prisma/client
  • cookie-parser                 yarn add cookie-parser
  • jsonwebtoken                 yarn add jsonwebtoken
  • nodemon                        yarn add -D nodemon

추가 설정하기

  • prisma/schema.prisma        provider = "사용할DB 이름 설정"
  • .env       DATABASE_URL = "사용할DB종류://DB관리자아이디:비밀번호@RDS 엔드포인트:Port번호/지정한 DB 이름

 

3. [게시판 프로젝트] Prisma 설계하기

 

요구사항을 바탕으로 Prisma의 모델을 작성해봅시다.

 

1) [요구사항] 사용자(Users) 테이블

 

model Users{
  userId      String @id @default(autoincrement()) @map("userId")
  password String        @unique                             @map("password")
  email        String        @unique                             @map("email")
  createdAt  DateTime @default(now())                  @map("createdAt")
  updatedAt DateTime @updateAt                          @map("updatedAt")

  @@map("Users")
}

 

 

2) [요구사항] 게시글(Posts) 테이블

 

model Posts{
  postId        Int @id   @default(autoincrement()) @map("postsId")
  title            String                                                 @map("title")
  content      String      @db.Text                            @map("content")
  createdAt  DateTime                                           @map("createdAt")
  updatedAt DateTime @updateAt                        @map("updatedAt")

  @@map("Posts")
}

 

 

3) [요구사항] 사용자 정보(UsersInfos) 테이블

 

model UserInfos{
  userInfoId Int @id @default(autoincrement()) @map("userInfoId")
  name String @map("name")
  age Int ? @map("age")
  gender String @map("gender")
  profileImage String ? @map("profileImage")
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updateAt @map("updatedAt")

  @@map("UserInfos")
}

 

 

4) [요구사항] 댓글(Comments) 테이블

 

model Comments{
  commentId Int @id @default(autoincrement()) @map("commentId")
  content String @map("content")
  createdAt DateTime @map("createdAt")
  updatedAt DateTime @updateAt @map("updatedAt")

  @@map("Comments")
}

 

위와 같이 요구사항을 바탕으로 DB의 Table들을 구현할 수 있습니다.

 

3. [게시판 프로젝트] DB 연관 관계 구성하기

 

1 : 1 관계 맺는 법 Opional Parameter (?)

1 : N 관계 맺는 법 배열 연산자([])

 

수정/삭제 시 처리

OnUpdate / OnDelete

 

Cascade : 종속이라는 뜻으로 부모 테이블의 행이 삭제되면 자식 테이블의 행도 삭제

 

SET NULL : 부모 테이블의 행이 삭제될 때, 자식 테이블의 해당 외래 키 컬럼 값을 NULL로 설정

                    자식 테이블의 해당 외래키 컬럼이 NULL 허용이어야 한다,

 

SET DEFAULT : 부모 테이블의 행이 삭제될 때, 자식 테이블의 외래 키 컬럼을 기본값으로 설정

                           이 경우 자식 테이블의 외래 키 컬럼에 기본값이 정의 돼 있어야 한다.

 

RESTRICT : 부모 테이블의 행이 삭제될 때, 자식 테이블에 해당 외래 키가 있는 한 삭제 불가능

                     즉, 참조 무결성을 보호하기 위해 삭제 작업이 거부 됩니다.

 

NO ACTION : RESTRICT와 비슷하지만, 참조 무결성 위반 여부를 확인하는 타이밍이 다르다.

                       트랜잭션이 완료될 때까지 삭제를 연기하고, 최종적으로 참조 무결성 검사를 수행하여

                       무결성 검사를 수행하여 문제가 있을 경우 에러를 발생시킵니다.

                       대부분의 데이터 베이스에서 NO Action은 기본적으로 설정된 동작입니다.

 

1) Users 테이블 연관관계 구축

 

model Users {
  userId    Int      @id @default(autoincrement()) @map("userId")
  email     String   @unique @map("email")
  password  String   @map("password")
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")

  userInfos UserInfos? // 사용자(Users) 테이블과 사용자 정보(UserInfos) 테이블이 1:1 관계를 맺습니다.
  posts     Posts[] // 사용자(Users) 테이블과 게시글(Posts) 테이블이 1:N 관계를 맺습니다.
  comments  Comments[] // 사용자(Users) 테이블과 댓글(Comments) 테이블이 1:N 관계를 맺습니다.

  @@map("Users")
}

 

2) UserInfos테이블 연관관계 구축

 

model UserInfos {
  userInfoId   Int      @id @default(autoincrement()) @map("userInfoId")
  userId       Int      @unique @map("userId") // 사용자(Users) 테이블을 참조하는 외래키
  name         String   @map("name")
  age          Int?     @map("age")
  gender       String   @map("gender")
  profileImage String?  @map("profileImage")
  createdAt    DateTime @default(now()) @map("createdAt")
  updatedAt    DateTime @updatedAt @map("updatedAt")

  // Users 테이블과 관계를 설정합니다.
  user Users @relation(fields: [userId], references: [userId], onDelete: Cascade)

  @@map("UserInfos")
}

 

3) Posts 테이블 연관관계 구축

 

model Posts {
  postId    Int      @id @default(autoincrement()) @map("postId")
  userId    Int      @map("userId") // 사용자(Users) 테이블을 참조하는 외래키
  title     String   @map("title")
  content   String   @map("content") @db.Text
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")

  // Users 테이블과 관계를 설정합니다.
  user     Users      @relation(fields: [userId], references: [userId], onDelete: Cascade)
  comments Comments[] // 게시글(Posts) 테이블과 댓글(Comments) 테이블이 1:N 관계를 맺습니다.

  @@map("Posts")
}

 

4) Comments 테으블 연관관계 구축

 

model Comments {
  commentId Int      @id @default(autoincrement()) @map("commentId")
  postId    Int      @map("postId") // 게시글(Posts) 테이블을 참조하는 외래키
  userId    Int      @map("userId") // 사용자(Users) 테이블을 참조하는 외래키
  content   String   @map("content")
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")

  // Posts 테이블과 관계를 설정합니다.
  post Posts @relation(fields: [postId], references: [postId], onDelete: Cascade)
  // Users 테이블과 관계를 설정합니다.
  user Users @relation(fields: [userId], references: [userId], onDelete: Cascade)

  @@map("Comments")
}

 

3. [게시판 프로젝트] Prisma DB, Table 생성하기

 

.env 파일에서 DATABASE_URL 수정하기

+

npx prisma db push

 

그 결과,

 

express_db 안에 

 

Comments, Posts, UserInfos, Users 테이블과 해당 컬럼들이 생성된 걸 볼 수 있습니다.

 

1) Users Table

 

2) UserInfos

 

userId는 외래키인데 Unique 제약조건이 같이 붙기 때문에,

DESC로 조회하면 Unique 제약조건만 우선해서 출력 됩니다.

 

3) Posts

 

4) Comments