일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Github
- HTTP
- 그래프 탐색
- 게임 서버 아키텍처
- 자바스크립트
- 이분 탐색
- ccw 알고리즘
- JavaScript
- 백준 28298번
- PROJECT
- Express.js
- visual studio code interactive 디버깅
- 그리디
- 백준 9328번
- string
- localstorage
- insomnia
- Prisma
- stack을 이용한 dfs
- router
- pm2
- html5
- MongoDB
- Next
- 백준 9466번
- ERD
- branch
- MySQL
- map
- vsc 디버깅
- Today
- Total
dh_0e
[Node.js] 강의 내용 개념 정리(2) (Prisma) 본문
Prisma
- ORM(Object Relational Mapping)으로써 Javascript 객체와 데이터베이스의 관계를 연결해주는 도구
- Node.js 환경에선 TypeORM, Prisma, Sequelize 등 다양한 ORM이 존재
- Prisma는 TypeScript에서도 사용할 수 있으며, ORM 개념을 학습하기 쉬움
- 여러가지 관계형 데이터베이스(RDB)를 사용할 수 있음
- MySQL에서 다루지 않는 Oracle, MariaDB, PostgreSQL와 같은 다양한 데이터베이스를 사용할 수 있음
Prisma vs mongoose
- mongoose의 경우 ODM(Object Document Mapping)으로 JS의 객체를 Document와 연결
- Prisma는 ORM(Object Relational Mapping)으로 JS 객체와 데이터베이스의 관계를 연결
- mongoose는 MongoDB 밖에 지원하지 않지만, Prisma는 RDBMS에 해당하는 다양한 데이터베이스를 사용할 수 있음
- mongoose는 Schema의 형태로 컬렉션에 대한 속성을 설정
- Prisma는 Model 형태로 테이블의 속성을 설정
- MongoDB의 컬렉션과 MySQL의 테이블은 동일한 위상을 가짐
ORM의 장단점
- 모든 코드를 SQL을 사용하는 Raw Query 형태로 구현하던 과거와 달리 Prisma를 사용하는 프로젝트를 구현할 때 Raw Query로 구현하지 않고, ORM을 사용함
- 프로덕션에서 사용하는 데이터베이스가 언제 바뀔지 알 수 없음
- ORM을 도입할 시 단순히 ORM의 속성값만 변경할 경우 언제든지 자유롭게 DB를 변경할 수 있어 개발할 때 선택의 폭이 넓어짐
- 데이터베이스에서 사용하는 DB or Table 속성이 변경되었을 때 빠르게 수정이 가능
nodemon 라이브러리
- 파일을 저장할 때마다 변경 사항을 감지, 자동으로 서버를 재시작해주는 라이브러리
- 개발 중 변경사항을 즉시 반영하여 개발 효율성을 향상시킬 수 있음 (Web의 live server같은 기능)
>> nodemon <실행할 JS 파일명>
schema.prisma
- Prisma가 사용할 데이터베이스의 실행 정보를 정의하기 위해 사용되는 파일
- datasource: Prisma가 어떤 DB 엔진을 사용하고 위치(URL)는 어디인지 등의 정보를 정의
- generator: Prisma 클라이언트를 생성하는 방식을 설정하는 구문
1:1 연관 관계 작성 예시
// schema.prisma
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 관계를 맺습니다.
@@map("Users")
}
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")
// User 이란 필드명으로 Users 테이블과 UserInfos의 관계를 설정합니다.
User Users @relation(fields: [UserId], references: [userId], onDelete: Cascade)
@@map("UserInfos")
}
💡 사용자(Users) 모델은 사용자 정보(UserInfos) 모델과 1:1 관계를 가지고 있습니다. 여기서, 1:1 관계란 한 사용자가 하나의 사용자 정보만 가질 수 있고, 한 사용자 정보는 한 사용자에게만 속할 수 있다는 것을 의미합니다.
이런 1:1 관계를 설정할 때는 다음과 같은 내용을 포함해야 합니다.
1. 관계를 설정하려는 모델(UserInfos)에서 어떤 모델과 관계를 맺을지(Users) 설정해야합니다.
2. 관계를 맺게되는 모델(Users)에서 어떤 모델이 관계를 맺는지(UserInfos) 설정해야합니다.
3. 관계를 맺게되는 모델(Users)에서, 타입을 지정할 때, Optional Parameter(?)를 지정해줘야합니다.
→ 사용자는 사용자 정보가 존재하지 않을 수 있기 때문이죠. 😉
그럼 이제, 사용자 정보(UserInfos) 모델에서 설정한 부분을 자세히 살펴보겠습니다.
Users
- 일반적인 Int, String과 같은 타입이 아닌, 참조할 다른 모델을 지정합니다.
- 사용자(Users) 모델을 참조하므로 Users로 작성되어있습니다.
fields
- 사용자 정보(UserInfos) 모델에서 사용할 외래키(Forien Key) 컬럼을 지정합니다.
- 여기선, userId 컬럼으로 외래키를 지정하였습니다.
references
- key: 참조하는 다른 모델의 Column를 지정합니다.
- 여기선, 사용자(Users) 모델의 userId 컬럼을 참조합니다.
onDelete | onUpdate
- 참조하는 모델이 삭제 or 수정될 경우 어떤 행위를 할 지 설정합니다.
- Cascade 옵션을 선택하여 사용자가 삭제될 경우 그에 연결된 사용자 정보도 함께 삭제되도록 설정하였습니다.
1:N 연관 관계 작성 예시
// schema.prisma
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 관계를 맺습니다.
@@map("Users")
}
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)
@@map("Posts")
}
💡 게시글(Posts) 모델은 사용자(Users) 모델과 N:1 관계를 가지고 있습니다. 여기서, 1:N 관계란 한 사용자는 여러개의 게시글을 작성할 수 있다는 것을 의미합니다.
이런 1:N 관계를 설정할 때는 다음과 같은 내용을 포함해야 합니다.
- 관계를 설정하려는 모델(Posts)에서 어떤 모델과 관계를 맺을지(Users) 설정해야합니다.
- 관계를 맺게되는 모델(Users)에서 어떤 모델이 관계를 맺는지(Posts) 설정해야합니다.
- 관계를 맺게되는 모델(Users)에서, 타입을 지정할 때, 배열 연산자([])를 작성해줘야합니다.
- → 사용자는, 여러개의 게시글을 가질 수 있기 때문이죠. 😉
현재 게시글 모델의 경우 작성한 사용자가 회원 탈퇴(onDelete)하게 될 경우 작성한 모든 게시글이 삭제되도록 구현되어 있습니다. 이런 설정은 @relation 어노테이션을 사용하여 지정합니다.
// Users 테이블과 관계를 설정합니다.
user Users @relation(fields: [userId], references: [userId], onDelete: Cascade)
여기서 User는 게시글(Posts)이 참조하는 다른 모델을 지정하고, fields는 게시글(Posts) 모델에서 사용할 외래키 컬럼을 지정합니다. references는 참조하는 다른 모델의 컬럼을 지정하고, onDelete는 잠조하는 모델이 삭제될 경우 어떤 행위를 할 지 설정합니다.
onDelete의 경우, Cascade 옵션으로 사용자가 삭제될 경우 연관된 게시글 또한 삭제되도록 설정하였습니다.
데이터베이스 URL
- Prisma가 어떤 데이터베이스와 어떻게 연결할 지를 알려주는 중요한 정보
- URL 내부에 엔진 유형, 사용자 아이디, 패스워드가 포함됨
Protocol: Prisma가 사용할 데이터베이스 엔진
Base URL: 데이터베이스의 엔드 포인트와 아이디, 패스워드, 포트 번호
Path: MySQL에서 사용할 데이터베이스 이름을 설정하는 구성 요소
Arguments: Prisma에서 데이터베이스 연결을 설정하는데 필요한 추가 옵션으로 최대 커넥션 갯수, 타임아웃 시간 등이 있음
Prisma model
- 특정 Table과 Column의 속성값을 입력하여, DB와 Express 프로젝트를 연결시켜줌
- schema.prisma 파일에서 model에 작성된 정보를 바탕으로 Prisma Client를 통해 JS에서 MySQL의 테이블을 조작할 수 있게 됨
- 결국 model 구문은 JS에서 MySQL의 테이블을 사용하기 위한 다리 역할을 수행함
Prisma CLI
npx prisma db push
- schema.prisma 파일에 정의된 설정값을 실제 데이터베이스에 반영
- 데이터베이스 구조를 변경하거나 새로운 테이블을 생성
- 내부적으로 prisma generate가 실행됨
prisma init
- Prisma를 사용하기 위한 초기 설정을 생성
- schema.prisma 파일과 같은 필수 설정 파일들이 생성됨
prisma generate
- Prisma Client를 생성하거나 업데이트함
- schema.prisma 파일에 변경 사항이 생겼거나, 데이터베이스 구조가 변경되었을 때, prisma generate로 Prisma Client를 최신 상태로 유지
prisma db pull
- 현재 데이터베이스의 구조를 prisma.schema 파일로 가져옴
- 데이터베이스에서 구조 변경이 발생했을 때, 이 명령어를 사용하여 prisma.schema를 최신 상태로 유지할 수 있음
- 이후 prisma generate 명령어를 따로 사용해 변경 사항을 Prisma Client에 반영할 수 있음
Prisma Client
- Prisma generate 시 해당 모델에 대한 정보가 node_modules 폴더 내에 있는 Prisma Client에 전달됨
- Prisma Schema에 정의한 데이터베이스 모델을 TypeScript 코드로 변환하여, 데이터베이스와 상호작용할 수 있게끔 해줌
Prisma Method
- Prisma는 mongoose와 동일하게, findMany(), findFirst(), findUnique() 등 다양한 메서드를 지원함
- mongoose는 Schema를 이용해 DB를 사용 / Prisma에선 Prisma Client를 이용해 MySQL의 데이터를 조작
Prisma where절에서의 논리 연산자 활용
Filtering and Sorting (Concepts) | Prisma Documentation
Use Prisma Client API to filter records by any combination of fields or related record fields, and/or sort query results.
www.prisma.io
Prisma 리팩토링
- new PrismaClient()를 이용해 JS에서 Prisma를 사용할 수 있도록 인스턴스 생성
const prisma = new PrismaClient();
- index.js에 생성하여 import하여 사용
'내일배움캠프 > Node.js[숙련]' 카테고리의 다른 글
[Node.js] 강의 내용 개념 정리(6) (Access Token, Refresh Token) (0) | 2024.05.27 |
---|---|
[Node.js] 강의 내용 개념 정리(5) (인증, 인가, 사용자 인증 미들웨어) (0) | 2024.05.27 |
[Node.js] 강의 내용 개념 정리(4) (JWT) (0) | 2024.05.24 |
[Node.js] 강의 내용 개념 정리(3) (Cookie, Session) (0) | 2024.05.24 |
[Node.js] 강의 내용 개념 정리(1) (RDB, SQL 제약 조건) (0) | 2024.05.22 |