[TIL] 20241120 TIL: ORM & PRISMA

Jaeyoung Ko·2024년 11월 20일
0

(1) Raw Query


A. Raw Query란 무엇인가?

Raw Query란 데이터베이스에 SQL을 이용하여 직접 쿼리를 요청하는 것이다.

Raw Query를 이용해 DDL로 테이블을 생성하고, DML로 테이블 목록과 데이터를 조회하는 기능을 구현할 수 있다.

// app.js
/** DDL: 테이블 생성 API **/
app.post('/api/tables/', async (req, res, next) => {
  const { tableName } = req.body;

  await connect.promise().query(`
      CREATE TABLE ${tableName}
      (
          id        INT         NOT NULL AUTO_INCREMENT PRIMARY KEY,
          name      VARCHAR(20) NOT NULL,
          createdAt DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP
      )`);

  return res.status(201).json({ message: 'success: table created' });
});
// app.js
/** DML: 데이터 삽입 API **/
app.post('/api/tables/:tableName/items', async (req, res, next) => {
  const { tableName } = req.params;
  const { name } = req.body;

  await connect.promise().query(`
      INSERT INTO ${tableName} (name)
      VALUES ('${name}')`);
  return res.status(201).json({ message: 'success: data inserted' });
});



B. Raw Query를 사용의 문제


1. 수정 / 유지 보수의 불편함

❓ 만약 구현한 API의 테이블 column을 수정하게 된다면?

column 이름 변경 시 모든 코드를 다시 수정해야만 한다.

2. 보안: SQL Injection

Raw Query를 이용하는 것은 사용자가 전달한 데이터를 데이터베이스에 직접 요청하는 방식이다. SQL Injection과 같은 공격은 유저가 악의적인 쿼리로 서버에 접속하여 관리자의 계정을 탈취하거나 다른 식으로 취약점을 공략하기 때문에 이러한 위험에도 취약하다.



C. Raw Query 문제의 해결: ORM의 등장

ORM은 Node에서 SQL을 직접 작성하지 않고, JS 만으로 데이터베이스를 조작할 수 있게 도와준다. 이런 ORM의 활용은 코드의 유지보수성을 높여준다.



  • 프로덕션에서 사용하는 데이터베이스의 변경 (ex. MySQL to Oracle)가 언제바뀔 지 알 수 없다.

유지보수 관리를 위해 이미 프로덕션에 사용된 db의 기술지원을 변경해야 하는 상황에 직면할 때, Raw Query로 작성했다면 모든 코드를 변경해야 한다.

ORM을 사용한다면 단순히 ORM의 속성값만 변경하는 것으로 자유롭게 DB를 변경할 수 있다.

  • 데이터베이스에서 사용하는 DB 또는 Table 속성이 변경되었을 때 빠르게 수정이 가능하다.





하지만, ORM도 Raw Query와 비교되는 문제점을 가지고 있다.

JOINUNION 연산자를 동시에 사용하는 복잡한 쿼리를 작성할 경우, ORM으로 구현하기 위해 SQL 보다는 ORM을 더 깊게 이해해야 하는 상황이 발생할 수 있고, 이로인해 원인과 결과가 뒤집힌 상황이 발생할 수도 있다.

이 뿐만 아니라, sub query를 포함하는 복잡한 쿼리를 작성하거나, ORM의 SQL로 변환해주는 시간 조차 아까운 극한의 성능을 요구하는 쿼리가 필요한 상황에서는 Raw Query를 사용하는 것이 더욱 좋을 수 있다.



이전에 혼자 학습할 때 TS를 사용하면서 함께 TypeORM을 응용한 적이 있는데, 이번 시간에는 좀 더 범용적이고 학습 곡선이 편한 PRISMA에 대해 알아보고자 한다.




(2) Prisma



PrismaORM(Object Relational Mapping)으로 JS 객체(Object)와 데이터베이스의 관계(Relation)연결(Mapping) 해주는 도구이다.

Prisma는 여러가지의 관계형 데이터베이스(RDB)를 사용할 수 있어, MySQL, PostgreSQL 등과 응용가능하다.

# yarn 프로젝트를 초기화
npm init -y

# express, prisma, @prisma/client 라이브러리를 설치
npm add express prisma @prisma/client

# nodemon 라이브러리를 DevDependency로 설치
npm add -D nodemon

# prisma 초기화
npx prisma init

참고: nodemon 라이브러리

nodemon은 파일을 저장 시 변경 사항을 감지하여 자동으로 서버를 재시작해주는 라이브러리이다. 이전처럼 node app.js 명령어를 이용하여 수동으로 재시작하지 않아도, 개발 중 변경사항을 즉시 반영하여 개발 효율성을 향상시킬 수 있도록 도와준다.



schema.prisma

schema.prisma 파일은 Prisma가 사용할 데이터베이스의 설정 정보를 정의하는 파일이다.

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
  • generator

    • Prisma 클라이언트를 생성하는 방식을 설정하는 구문
  • datasource

    • 데이터베이스에 대한 정의 : 어떤 db 엔진을 사용할 것인지, db URL 등 정의



여기서 데이터베이스 url이란 무엇인가

A. 데이터베이스 URL


Prisma가 어떤 데이터베이스와 어떻게 연결할지를 알려주는 중요한 정보로 URL 내부에는 데이터베이스 엔진 유형, 사용자 아이디, 패스워드와 같은 정보를 포함한다.

  • Protocol
    • 데이터베이스 엔진 정보
    • ex. postgresql, sqllite, mysql
  • Base URL
    • 데이터베이스의 end point아이디, 패스워드, 포트 번호
    • <Id>:<Password>@<RDS Endpoint>:<Port>
  • Path
    • MySQL에서 사용할 데이터베이스 이름을 설정하는 구성 요소
  • Arguments
    • 데이터베이스 연결 설정의 추가 옵션
    • ex. 최대 커넥션 갯수, 타임아웃 시간

// 데이터 베이스 URL 형태

<db엔진>://<Id>:<Password>@<RDS Endpoint>:<Port>/<사용할 db 이름>





B. Prisma Model


Prismamodel 구문은 특정 TableColumn의 속성값을 입력하여, 데이터베이스와 Express를 연결한다.

  • Prisma를 사용 시 가장 많이 작성하게 될 구문.
  • schema.prisma 파일에서는 model에 작성한 정보로 Prisma Client를 통해 JS로 MySQL의 테이블을 조작

🧩 Prisma CLI

prisma db push
schema.prisma 파일에 정의된 설정값을 실제 데이터베이스에 반영 (내부적으로 prisma generate 실행)
데이터베이스 구조를 변경하거나 새로운 테이블을 생성


prisma init
schema.prisma 같은 초기 설정 파일 생성


prisma generate
Prisma Client를 생성/업데이트


prisma db pull
현재 연결된 데이터베이스의 구조를 prisma.schema 파일로 가져와서 Prisma Schema를 최신 상태로 유지
이후 prisma generate 명령어 사용하여 반영 가능


profile
안녕하세요, 고재영입니다. 언제나 즐겁게 살려고 노력합니다.

0개의 댓글