이글을 읽기전에 ORM에 대해 알아야 합니다.
1. Prisma란?
Prisma는 현대적인 ORM도구로, 데이터베이스와의 상호작용을 쉽고 효율적으로 관리하는 도구이다. Prisma는 개발자가 데이터베이스 스키마를 정의하고, 데이터베이스에 대한 질의 및 조작을 수행하는 작업을 단순화하는데 사용한다.
흠... ORM이라는 것은 알겠는데 그럼 기존 ORM과 어떤 차이가 있을까?
prism 공식 사이트로가면 prisma를 '차세대 Node.js와 TypeScript ORM'이라고 소개하고있다.
무엇이 다르기에 '차세대'라는 단어 까지 넣어가면 강조했을까 궁금했다.
그래서 찾아보니 이유가 다 있었다.
📕 why Next-generation ORM ?
Prisma는 기존 ORM과 근본적으로 다르며 일반적으로 기존 ORM이 겪는 많은 문제들을 겪지 않는 새로운 종류의 ORM이다.
전통적인 ORM은 테이블을 프로그래밍 언어의 모델 클래스에 매핑하여 관계형 데이터베이스 작업을 위한 객체 지향 방식을 제공한다. 이 접근 방식은 Object-relational 임피던스 불일치로 인해 발생하는 많은 문제를 야기한다.
Prisma는 이러한 전통적인 ORM과 근본적으로 다르게 동작한다.
Prisma를 사용하면 선언적인 Prisma 스키마에서 모델을 정의하며, 이는 데이터베이스 스키마와 프로그래밍 언어의 모델에 대한 SSOT(single source of truth)으로 작용한다. 애플리케이션 코드에서는 Prisma Client를 사용하여 복잡한 모델 인스턴스를 관리하는 오버헤드 없이 데이터베이스에서 데이터를 안전한 유형으로 읽고 쓸 수 있다. 이렇게 하면 Prisma Client가 항상 일반 JavaScript 객체를 반환하므로 데이터 쿼리 프로세스가 훨씬 자연스러울 뿐만 아니라 예측 가능하게 만든다.
1️⃣ 원시 SQL 완전한 제어, 낮은 생산성
원시 SQL을 사용하면 데이터베이스 작업을 완전히 제어할 수 있으나 일반 SQL문자열을 데이터베이스로 보내는 것은 번거롭고 많은 오버헤드(수동 연결처리, 반복적인 사용구 등)가 수반되기 때문에 생산성이 저하된다.
또한 쿼리 결과에 대한 유형 안정성을 언지 못한다. 물론 결과를 수동으로 입력할 수 있지만 이는 엄청난 작업량이며 입력을 동기화하기 위해 데이터베이스 스키마 또는 쿼리를 변경할 때마다 대대적인 리팩터링이 필요하다.
또한 SQL 쿼리를 일반 문자열로 제출하면 편집기에서 자동 완성 기능을 사용할 수 없다.
2️⃣ SQL 쿼리 빌더 : 높은 제어, 중간 생산성
높은 수준의 제어를 유지하고 더 나은 생상선을 제공하는 일반적인 솔루션은 SQL 쿼리 빌더(예: knex.js)를 사용하는 것이다. 이러한 종류의 도구는 SQL 쿼리를 구성하기 위한 프로그래밍 방식의 추상화를 제공한다.
SQL 쿼리 빌더의 가장 큰 단점은 애플리케이션 개발자들이 여전히 데이터를 SQL의 관점에서 고려해야 한다는 것이다. 이는 관계형 데이터를 객체로 변환하는 인지적 및 실용적인 비용을 발생시킨다. 또 다른 문제는 SQL 쿼리를 정확히 이해하지 못하면 실수하기 쉽다는 것이다.
3️⃣ 전통적인 ORM: 제어력 감소, 생산성 향상
ORM은 SQL을 추상화하여 애플리케이션 모델을 클래스로 정의할 수 있도록 하며, 이러한 클래스는 데이터베이스의 테이블에 매핑된다. 그런 다음 모델 클래스의 인스턴스에서 메서드를 호출하여 데이터를 읽고 쓸 수 있다.
하지만 ORM에는 함정이 존재한다. 친숙한 점 표기법을 사용하여 관계를 순환할 수 있는 것처럼 보이지만 내부적으로 ORM은 비용이 많이 들고 애플리케이션 속도를 크게 저하시킬 가능성이 있는 SQL JOIN을 생성한다.
쉽게말해 기존 ORM은 모델을 추상화하여 관계형 데이터가 오브젝트에 쉽게 매핑 매핑될 수 있다는 잘못된 가정에 기반을 두고 있어 많은 복잡성과 함정이 발생한다.
2. Prisma Components
Prisma가 제공하는 도구를 알아보기전 Prisma 스키마에대해 먼저 알아보자
📌 Prisma 스키마
Prisma 스키마는 Prisma ORM에서 사용되는 데이터 모델을 정의하는 파일이다. Prisma 스키마는 데이터베이스 스키마와 애플리케이션 모델 간의 매핑을 담당한다.
Prisma 스키마는 데이터베이스 테이블, 열, 관계 등의 구조를 정의하고, Prisma에서 사용할 수 있는 모델과 필드를 선언한다.
이 스키마 파일을 사용하여 Prisma는 데이터베이스와의 상호작용을 추상화하고, Prisma Client를 통해 데이터베이스 쿼리를 수행할 때 유효성 검사와 타입 안전성을 제공한다.
Prisma 스키마는 Prisma CLI를 사용하여 관리되며, 데이터베이스 스키마의 변경 사항을 추적하고 관리할 수 있다. 이를 통해 데이터베이스 스키마의 버전 관리와 마이그레이션을 용이하게 할 수 있다.
Prisma은 다음과 같은 도구를 제공한다.
- Prisma 클라이언트 : 애플리케이션에서 사용하기 위한 자동 생성 및 유형 안전 데이터베이스 클라이언트이다.
- Prisma Migrate : 선언적 데이터 모델링 및 마이그레이션 도구이다.
- Prisma Studio : 데이터베이스에서 데이터를 찾아보고 관리하기 위한 최신 GUI이다.
1️⃣ Prisma Client
Prisma Client 는 Prisma에서 생성된 데이터베이스 접근 라이브러리다. Prisma Client를 사용하면 Prisma 스키마에 정의된 모델과 관련된 데이터를 읽고 쓸 수 있다. Prisma Client는 데이터베이스와 상호작용하기 위한 일련의 메서드와 함수를 제공하며, 이를 통해 데이터베이스 쿼리를 안전하게 수행하고 결과를 반환할 수 있다.
2️⃣ Prisma Migrate
Prisma Migrate는 Prisma에서 제공하는 데이터베이스 마이그레이션 도구이다. 즉 Prisma 스키마를 필요한 SQL로 변환하여 데이터베이스의 테이블을 생성하고 변경한다. Prisma CLI에서 제공하는 Prisma migrate 명령을 통해 사용할 수 있다. (더 자세한 내용) (데이터베이스 마이그레이션이란 데이터베이스 스키마를 변경하거나 업데이트하는 작업을 의미한다. )
Prisma Migrate를 사용하면 Prisma 스키마의 변경 사항을 추적하고, 데이터베이스 스키마에 반영하기 위한 마이그레이션 파일을 생성할 수 있다. 이 마이그레이션 파일은 이전 스키마와 새로운 스키마 간의 차이점을 정의하고, 데이터베이스를 해당 변경 사항으로 업데이트하는 데 사용된다.
Prisma Migrate를 통해 데이터베이스 스키마를 관리하면 데이터베이스 스키마 변경을 버전 관리하고, 여러 환경에서 일관된 데이터베이스 구조를 유지할 수 있다. 또한, 데이터베이스 마이그레이션은 애플리케이션 배포 시 데이터베이스를 쉽게 업데이트하고 유지할 수 있도록 도와준다.
데이터 베이스 스키마를 생성하는 두 가지 방법
- prisma db push : 마이그레이션 없이 Prisma 스키마를 기반으로 데이터베이스 스키마를 생선한다. 로컬 프로토타이핑 중에 사용하기 위한 것
- prisma migrate dev: Prisma 스키마의 변경 사항을 기반으로 SQL 마이그레이션을 생성하고 이를 적용하여 Prisma Client를 생성한다.
마이그레이션을 생성하지 않고도 데이터베이스 스키마를 Prisma 스키마와 일치시킬 수 있는 간단한 명령어
prisma db push
Prisma를 시작하거나 모델이 명확하게 정의되지 않은 아이디어의 프로토타이핑을 진행하는 동안, 모델의 적합성을 계속 확인하고자 할 때 지속적으로 prisma migrate를 사용하는 것보다 prisma db push를 사용하는 것이 좋다.
3️⃣ Prisma Studio
데이터베이스 내부를 한 눈에 볼 수 있고 데이터를 편집도 할 수 있는 GUI이다.
prisma 사용을 추천하는 경우
1. 데이터베이스와 통신하는 server-side apllication을 구축하고자 할 때
서버사이드 애플리케이션은 주로 REST, GraphQL 또는 gRPC와 같은 기술을 통해 데이터 작업을 expose하는 API서버이다.
이러한 애플리케이션은 대부분 마이크로 서비스 또는 단일체 앱으로 구축되며, 장기간 실행되는 서버 또는 서버리스 함수로 배포된다. Prisma는 이러한 모든 애플리케이션 및 배포 모델에 적합하다.
3. 📚 How does it work?
간단하게 동작하는 순서와 방식에대해 알아보자.
1. 프리즈마 설치
2. Prisma 스키마에서 데이터 모델링
3. Prisma Migrate로 마이그레이션을 실행하여 데이터 베이스 테이블 생성
4. Prisma 클라이언트를 사용하여 데이터베이스에 쿼리를 보내거나 받는다.
여기서 의문점이 있다. Prisma 클라이언트는 어떻게 데이터베이스와 쿼리를 주고 받을까 ?? 바로 '쿼리 엔진'의 도움으로 주고받을 수 있다.
📌 Query engine
기본적으로 Prisma Client는 쿼리 엔진을 Node-API 라이브러리로 로드한다. (Node-API 라이브러리 접근 방식은 Prisma 클라이언트와 쿼리 엔진 간의 통신 오버 헤드를 줄이기 때문에 권장된다.
첫 번째 Prisma Client 쿼리가 호출되거나 PrismaClient 인스턴스에서 $connect() 메서드가 호출될 때 쿼리 엔진이 시작된다. 쿼리 엔진이 시작되면 연결 풀이 생성되고 데이터베이스로의 물리적인 연결을 관리한다. 이후로 Prisma Client는 데이터베이스로 쿼리를 보낼 준비가 된다. (예: findUnique, findMany, create 등).
$disconnect()가 호출되면 쿼리 엔진이 중지되고 데이터베이스 연결이 닫힌다.
📌 쿼리 엔진의 역할
- 연결 풀에서 물리적인 데이터베이스 연결을 관리한다.
- Prisma Client Node.js 프로페스로부터 수신된 쿼리를 받는다.
- SQL 쿼리를 생성한다.
- 데이터베이스로 SQL 쿼리를 전송한다.
- 데이터베이스로부터의 응답을 처리하고 Prisma Client로 다시 보낸다.
Reference
https://www.youtube.com/watch?v=EEDGwLB55bI&t=1s
https://www.prisma.io/blog/prisma-the-complete-orm-inw24qjeawmb